浅析JS中什么是自定义react数据验证组件


Posted in Javascript onOctober 19, 2018

我们在做前端表单提交时,经常会遇到要对表单中的数据进行校验的问题。如果用户提交的数据不合法,例如格式不正确、非数字类型、超过最大长度、是否必填项、最大值和最小值等等,我们需要在相应的地方给出提示信息。如果用户修正了数据,我们还要将提示信息隐藏起来。

有一些现成的插件可以让你非常方便地实现这一功能,如果你使用的是knockout框架,那么你可以借助于Knockout-Validation这一插件。使用起来很简单,例如我下面的这一段代码:

ko.validation.locale('zh-CN');
ko.validation.rules['money'] = {
 validator: function (val) {  
  if (val === '') return true;  return /^\d+(\.\d{1,2})?$/.test(val);
 },
 message: '输入的金额不正确'};
ko.validation.rules['moneyNoZero'] = {
 validator: function (val) {  
  if (val === '') return true;  return isNaN(val) || val != 0;
 },
 message: '输入的金额不能为0'};
ko.validation.registerExtenders();var model = {
 MSRP: ko.observable(0),
 price: ko.observable().extend({ required: true, number: true, min: 10000, money: true, moneyNoZero: true }),
 licence_service_fee: ko.observable().extend({ required: true, money: true }),
 purchase_tax: ko.observable().extend({ required: true, money: true }),
 vehicle_tax: ko.observable().extend({ required: true, money: true }),
 insurance: ko.observable().extend({ required: true, money: true }),
 commercial_insurance: ko.observable().extend({ required: true, money: true }),
 mortgage: ko.observable(''),
 interest_discount: ko.observable(''),
 allowance: ko.observable().extend({ money: true }),
 special_spec_fee_explain: ko.observable(''),
 has_extra_fee: ko.observable(false),
 is_new_energy: ko.observable(false)
};
model.extra_fee_explain = ko.observable().extend({
 required: {
  onlyIf: function () {   
   return model.has_extra_fee() === true;
  }
 }
});
model.extra_fee = ko.observable().extend({
 required: {
  onlyIf: function () {   
   return model.has_extra_fee() === true;
  }
 },
 money: {
  onlyIf: function () {   
   return model.has_extra_fee() === true;
  }
 }
});
model.new_energy_allowance_explain = ko.observable().extend({
 required: {
  onlyIf: function () {   
   return model.is_new_energy() === true;
  }
 }
});
model.total_price = ko.computed(function () { 
 var _total = Number(model.price()) + Number(model.licence_service_fee()) +Number(model.purchase_tax()) + Number(model.vehicle_tax()) +Number(model.insurance()) + Number(model.commercial_insurance()); 
  if (model.has_extra_fee()) {
  _total += Number(model.extra_fee());
 } 
 if (model.is_new_energy()) {
  _total -= Number(model.new_energy_allowance());
 } 
 return isNaN(_total) ? '0' : _total.toFixed(2).replace(/(\.0*$)|(0*$)/, '');
});
model.errors = ko.validation.group(model);
ko.applyBindings(model);

更多使用方法可以查看github上的说明文档和示例。

但是,如果我们前端使用的是React框架,如何来实现和上面knockout类似的功能呢?我们可以考虑将这一相对独立的功能抽出来,写成一个React组件。看下面的代码:

class ValidationInputs extends React.Component {
 constructor(props) {
 super(props); this.state = {
  isValid: true,
  required: this.props.required,
  number: this.props.number,
  min: this.props.min,
  max: this.props.max,
  money: this.props.money,
  data: null,
  errors: ""
 }
 }
 componentWillReceiveProps(nextProps) { 
 var that = this; 
 if (this.state.data !== nextProps.data) {  
  return setStateQ({data: nextProps.data}, this).then(function () {  
   return that.handleValidation();
  });
 }
 }
 handleValidation() { var fields = this.state.data; // required validation
 if(this.state.required && isNilOrEmpty(fields)){  
  return setStateQ({errors: '必须填写', isValid: false}, this);
 } 
 // number validation
 if (this.state.number) {  
  if (isNaN(fields)) {  
   return setStateQ({errors: '请输入数字', isValid: false}, this);
  }  
  if (!isNilOrEmpty(this.state.min) && !isNaN(this.state.min) && Number(this.state.min) > Number(fields)) {  
  return setStateQ({errors: '输入值必须大于等于' + this.state.min, isValid: false}, this);
  }  
  if (!isNilOrEmpty(this.state.max) && !isNaN(this.state.max) && Number(this.state.max) < Number(fields)) {  
   return setStateQ({errors: '输入值必须小于等于' + this.state.max, isValid: false}, this);
  }
 } // money validation
 if (this.state.money) {  
   if (fields.length > 0 && !/^\d+(\.\d{1,2})?$/.test(fields)) {  
    return setStateQ({errors: '输入的金额不正确', isValid: false}, this);
   }
 } 
  return setStateQ({errors: '', isValid: true}, this);
 }
 render() { return <span className="text-danger">{this.state.errors}</span> }
}

该组件支持的验证项有:

required:true | false 检查是否必填项。

number:true | false 检查输入的值是否为数字。

如果number为true,可通过max和min来验证最大值和最小值。max和min属性的值都必须为一个有效的数字。

money:true | false 验证输入的值是否为一个有效的货币格式。货币格式必须为数字,最多允许有两位小数。

如何使用?

我们在父组件的render()方法中加入该组件的引用:

<p className="item">
 <p className="col-xs-4">净车价:</p>
 <p className="col-xs-7">
  <input type="text" className="form-control" placeholder="0" value={this.state.price} onChange={this.changePrice.bind(this)}/>
  <ValidationInputs ref="validation1" data={this.state.price} required="true" number="true" min="10000" max="99999999" money="true"/>
 </p>
 <p className="col-xs-1 text-center">元</p>
 <p className="clear"></p></p>

我们将price变量加到父组件的state中,并给input控件绑定onChange事件,以便用户在修改了文本框中的内容时,price变量的值可以实时传入到ValidationInputs组件中。这样,ValidationInputs组件就可以立即通过自己的handleValidation()方法对传入的数据按照预先设定的规则进行验证,并决定是否显示错误信息。

注意,这里我们在引用ValidationInputs组件时,设置了一个ref属性,这是为了方便在父组件中获得ValidationInputs组件的验证结果(成功或失败)。我们可以在父组件中通过下面这个方法来进行判断(假设父组件中引用了多个ValidationInputs组件,并且每个引用都设置了不同的ref值):

// 父组件调用该方法来判断所有的输入项是否合法
checkInputs() { 
 for (var r in this.refs) {  
   var _ref = this.refs[r];  
   if (_ref instanceof ValidationInputs) {   
    if (!_ref.state.isValid) return false;
  }
 } 
 return true;
}

这样,我们在父组件提交数据之前,可以通过这个方法来判断所有的数据项是否都已经通过验证,如果未通过验证,则不提交表单。

总结

以上所述是小编给大家介绍的JS中什么是自定义react数据验证组件,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
云网广告中的代码,提示出错,大家找找
Nov 21 Javascript
js 新浪的一个图片播放图片轮换效果代码
Jul 15 Javascript
JavaScript 闭包在封装函数时的简单分析
Nov 28 Javascript
Javascript中的回调函数和匿名函数的回调示例介绍
May 12 Javascript
Javascript冒泡排序算法详解
Dec 03 Javascript
node.js中的fs.createReadStream方法使用说明
Dec 17 Javascript
JS显示下拉列表框内全部元素的方法
Mar 31 Javascript
浅谈JavaScript中变量和函数声明的提升
Aug 09 Javascript
JS完成画圆圈的小球
Mar 07 Javascript
使用classList来实现两个按钮样式的切换方法
Jan 24 Javascript
微信小程序 函数防抖 解决重复点击消耗性能问题实现代码
Sep 12 Javascript
全面解析js中的原型,原型对象,原型链
Jan 25 Javascript
在小程序Canvas中使用measureText的方法示例
Oct 19 #Javascript
webstorm中配置Eslint的两种方式及差异比较详解
Oct 19 #Javascript
clipboard在vue中的使用的方法示例
Oct 19 #Javascript
详解在vue-cli项目下简单使用mockjs模拟数据
Oct 19 #Javascript
ES6 系列之 Generator 的自动执行的方法示例
Oct 19 #Javascript
js中自定义react数据验证组件实例详解
Oct 19 #Javascript
值得收藏的八个常用的js正则表达式
Oct 19 #Javascript
You might like
星际初学者游戏中永远要做的事
2020/03/04 星际争霸
Codeigniter购物车类不能添加中文的解决方法
2014/11/29 PHP
PHP单链表的实现代码
2016/07/05 PHP
PHP判断是否微信访问的方法示例
2019/03/27 PHP
关于B/S判断浏览器断开的问题讨论
2008/10/29 Javascript
js 页面执行时间计算代码
2009/03/04 Javascript
js正确获取元素样式详解
2009/08/07 Javascript
JavaScript Sort 表格排序
2009/10/31 Javascript
九种js弹出对话框的方法总结
2013/03/12 Javascript
jquery()函数的三种语法介绍
2013/10/09 Javascript
JavaScript实现班级随机点名小应用需求的具体分析
2014/05/12 Javascript
JavaScript获取Url里的参数
2014/12/18 Javascript
Javascript操作dom对象之select全面解析
2017/04/24 Javascript
Vue渲染函数详解
2017/09/15 Javascript
jQuery实现获取table中鼠标click点击位置行号与列号的方法
2017/10/09 jQuery
JS中数组与对象的遍历方法实例小结
2018/08/14 Javascript
微信小程序解除10个请求并发限制
2018/12/18 Javascript
jquery css实现流程进度条
2020/03/26 jQuery
JavaScript中数组去重的5种方法
2020/07/04 Javascript
Python利用pyHook实现监听用户鼠标与键盘事件
2014/08/21 Python
深入Python函数编程的一些特性
2015/04/13 Python
python定时检查某个进程是否已经关闭的方法
2015/05/20 Python
python3.6利用pyinstall打包py为exe的操作实例
2018/10/31 Python
如何基于Python批量下载音乐
2019/11/11 Python
pytorch实现线性拟合方式
2020/01/15 Python
Django框架安装及项目创建过程解析
2020/09/14 Python
阿联酋航空假期:Emirates Holidays
2018/03/20 全球购物
《和我们一样享受春天》教学反思
2014/02/07 职场文书
《厄运打不垮的信念》教学反思
2014/04/13 职场文书
学雷锋的心得体会
2014/09/04 职场文书
《周恩来的四个昼夜》观后思想汇报范文两篇
2014/09/10 职场文书
2014年残疾人工作总结
2014/12/06 职场文书
2014年前台文员工作总结
2014/12/08 职场文书
SQL Server中交叉联接的用法详解
2021/04/22 SQL Server
vue3使用vuedraggable实现拖拽功能
2022/04/06 Vue.js
电脑开机弹出documents文件夹怎么回事?弹出documents文件夹解决方法
2022/04/08 数码科技