浅析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 相关文章推荐
一段批量给页面上的控件赋值js
Jun 19 Javascript
jsTree 基于JQuery的排序节点 Bug
Jul 26 Javascript
jQuery EasyUI API 中文文档 - Draggable 可拖拽
Sep 29 Javascript
javascript匿名函数实例分析
Nov 18 Javascript
JQuery遍历元素的后代和同胞实现方法
Sep 18 Javascript
JavaScript实现汉字转换为拼音的库文件示例
Dec 22 Javascript
解决Vue2.x父组件与子组件之间的双向绑定问题
Mar 06 Javascript
详解通过源码解析Node.js中cluster模块的主要功能实现
May 16 Javascript
通过js给网页加上水印背景实例
Jun 17 Javascript
手写Vue源码之数据劫持示例详解
Jan 04 Vue.js
vue实现轮播图帧率播放
Jan 26 Vue.js
react使用antd的上传组件实现文件表单一起提交功能(完整代码)
Jun 29 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
PHP常用正则表达式集锦
2014/08/17 PHP
php为字符串前后添加指定数量字符的方法
2015/05/04 PHP
PHP实现发送邮件的方法(基于简单邮件发送类)
2015/12/17 PHP
php获取文件后缀的9种方法
2016/03/22 PHP
nginx下安装php7+php5
2016/07/31 PHP
使用Zookeeper分布式部署PHP应用程序
2019/03/15 PHP
javascript 数字格式化输出的实现代码
2013/12/10 Javascript
xmlhttp缓存清除的2种解决方法
2013/12/13 Javascript
js 时间格式与时间戳的相互转换示例代码
2013/12/25 Javascript
JavaScript实现班级随机点名小应用需求的具体分析
2014/05/12 Javascript
手机端点击图片放大特效PhotoSwipe.js插件实现
2016/08/24 Javascript
关于jquery中动态增加select,事件无效的快速解决方法
2016/08/29 Javascript
JS动态添加选项案例分析
2016/10/17 Javascript
JavaScript如何实现图片懒加载(lazyload) 提高用户体验(增强版)
2016/11/30 Javascript
CodeMirror js代码加亮使用总结
2017/03/25 Javascript
JavaScript与Java正则表达式写法的区别介绍
2017/08/15 Javascript
史上最全JavaScript常用的简写技巧(推荐)
2017/08/17 Javascript
vue和better-scroll实现列表左右联动效果详解
2019/04/29 Javascript
vue+elementUI组件table实现前端分页功能
2020/11/15 Javascript
three.js欧拉角和四元数的使用方法
2020/07/26 Javascript
使用python编写android截屏脚本双击运行即可
2014/07/21 Python
详解Python3中字符串中的数字提取方法
2017/01/14 Python
python实现石头剪刀布小游戏
2021/01/20 Python
将python图片转为二进制文本的实例
2019/01/24 Python
python保留格式汇总各部门excel内容的实现思路
2020/06/01 Python
python相对企业语言优势在哪
2020/06/12 Python
Python高阶函数与装饰器函数的深入讲解
2020/11/10 Python
阿迪达斯英国官方网站:adidas英国
2019/08/13 全球购物
德国网上超市:myTime.de
2019/08/26 全球购物
C语言怎样定义和声明全局变量和函数最好
2013/11/26 面试题
简单叙述一下MYSQL的优化
2016/05/09 面试题
幼师专业毕业生自荐信
2013/09/29 职场文书
给分销商的致歉信
2014/01/14 职场文书
本科生自荐信
2014/06/18 职场文书
群众路线自查报告及整改措施
2014/11/04 职场文书
用Python可视化新冠疫情数据
2022/01/18 Python