浅析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 相关文章推荐
javascript中typeof的使用示例
Dec 19 Javascript
jQuery事件绑定on()、bind()与delegate() 方法详解
Jun 03 Javascript
Javascript的表单验证-提交表单
Mar 18 Javascript
url中的特殊符号有什么含义(推荐)
Jun 17 Javascript
AngularJS 入门教程之HTML DOM实例详解
Jul 28 Javascript
老生常谈jacascript DOM节点获取
Apr 17 Javascript
vue之数据交互实例代码
Jun 16 Javascript
解决IE7中使用jQuery动态操作name问题
Aug 28 jQuery
解决vue2.0路由跳转未匹配相应用路由避免出现空白页面的问题
Aug 24 Javascript
手动下载Chrome并解决puppeteer无法使用问题
Nov 12 Javascript
JavaScript数据结构与算法之二叉树遍历算法详解【先序、中序、后序】
Feb 21 Javascript
详解ES6实现类的私有变量的几种写法
Feb 10 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
德劲1104的电路分析与改良
2021/03/01 无线电
Thinkphp的volist标签嵌套循环使用教程
2014/07/08 PHP
php两种无限分类方法实例
2015/04/21 PHP
PHP和MYSQL实现分页导航思路详解
2017/04/11 PHP
PHP SESSION跨页面传递失败解决方案
2020/12/11 PHP
js使用split函数按照多个字符对字符串进行分割的方法
2015/03/20 Javascript
浅谈JavaScript变量的自动转换和语句
2016/06/12 Javascript
微信小程序购物商城系统开发系列-工具篇的介绍
2016/11/21 Javascript
jquery实现input框获取焦点的方法
2017/02/06 Javascript
ES5 ES6中Array对象去除重复项的方法总结
2017/04/27 Javascript
node跨域请求方法小结
2017/08/25 Javascript
JS如何设置元素样式的方法示例
2017/08/28 Javascript
webpack-dev-server自动更新页面方法
2018/02/22 Javascript
JS限制输入框输入的实现代码
2018/07/02 Javascript
说说如何在Vue.js中实现数字输入组件的方法
2019/01/08 Javascript
jQuery 动画与停止动画效果实例详解
2020/05/19 jQuery
用python 制作图片转pdf工具
2015/01/30 Python
在Python中操作字典之fromkeys()方法的使用
2015/05/21 Python
玩转python selenium鼠标键盘操作(ActionChains)
2020/04/12 Python
浅析python递归函数和河内塔问题
2017/04/18 Python
python交互式图形编程实例(二)
2017/11/17 Python
Python 记录日志的灵活性和可配置性介绍
2018/02/27 Python
python线程中同步锁详解
2018/04/27 Python
django的登录注册系统的示例代码
2018/05/14 Python
python实现邮件发送功能
2019/08/10 Python
python爬虫 urllib模块反爬虫机制UA详解
2019/08/20 Python
基于PyQT实现区分左键双击和单击
2020/05/19 Python
Hotels.com加拿大:领先的在线住宿网站
2018/10/05 全球购物
使用useBean标志初始化BEAN时如何接受初始化参数
2012/02/11 面试题
GWT的应用有哪两种部署模式
2012/12/21 面试题
乡镇党建工作汇报材料
2014/10/27 职场文书
2014年房产经纪人工作总结
2014/12/08 职场文书
党风廉政承诺书2016
2016/03/25 职场文书
html form表单基础入门案例讲解
2021/07/21 HTML / CSS
vue 数字翻牌器动态加载数据
2022/04/20 Vue.js
一文了解Java动态代理的原理及实现
2022/07/07 Java/Android