浅析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 省地市级联选择
Feb 07 Javascript
JS获取URL中的参数数据
Dec 05 Javascript
javascript实时显示当天日期的方法
May 20 Javascript
Knockoutjs 学习系列(二)花式捆绑
Jun 07 Javascript
浅析location.href跨窗口调用函数
Nov 22 Javascript
input获取焦点时底部菜单被顶上来问题的解决办法
Jan 24 Javascript
vue 2.0路由之路由嵌套示例详解
May 08 Javascript
基于 Vue.js 之 iView UI 框架非工程化实践记录(推荐)
Nov 21 Javascript
js replace 全局替换的操作方法
Jun 12 Javascript
Vue CLI3 开启gzip压缩文件的方式
Sep 30 Javascript
JS 实现获取验证码 倒计时功能
Oct 29 Javascript
了解Javascript中函数作为对象的魅力
Jun 19 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中$_REQUEST、$_POST、$_GET的区别和联系小结
2011/11/23 PHP
PHP抓取、分析国内视频网站的视频信息工具类
2014/04/02 PHP
ci检测是ajax还是页面post提交数据的方法
2014/11/10 PHP
php 使用file_get_contents读取大文件的方法
2014/11/13 PHP
跨浏览器PHP下载文件名中的中文乱码问题解决方法
2015/03/05 PHP
php检测url是否存在的方法
2015/04/14 PHP
PHP getDocNamespaces()函数讲解
2019/02/03 PHP
获取URL地址中的文件名和参数的javascript代码
2009/09/02 Javascript
浅析JavaScript中的类型和对象
2013/11/29 Javascript
JavaScript调用ajax获取文本文件内容实现代码
2014/03/28 Javascript
php,js,css字符串截取的办法集锦
2014/09/26 Javascript
javascript中in运算符用法分析
2015/04/28 Javascript
JavaScript类型系统之Object详解
2016/01/07 Javascript
修复jQuery tablesorter无法正确排序的bug(加千分位数字后)
2016/03/30 Javascript
AngularJS入门教程之迭代器过滤详解
2016/08/18 Javascript
DOM 事件的深入浅出(一)
2016/12/05 Javascript
vue中axios请求的封装实例代码
2019/03/23 Javascript
vue自动路由-单页面项目(非build时构建)
2019/04/30 Javascript
vue路由跳转传参数的方法
2019/05/06 Javascript
vue表单验证之禁止input输入框输入空格
2020/12/03 Vue.js
[57:37]EG vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python实现在Linux系统下更改当前进程运行用户
2015/02/04 Python
Python基于DES算法加密解密实例
2015/06/03 Python
听歌识曲--用python实现一个音乐检索器的功能
2016/11/15 Python
Python实现并行抓取整站40万条房价数据(可更换抓取城市)
2016/12/14 Python
django中的setting最佳配置小结
2017/11/21 Python
基于Python函数的作用域规则和闭包(详解)
2017/11/29 Python
Python编程使用tkinter模块实现计算器软件完整代码示例
2017/11/29 Python
单位人事专员介绍信
2014/01/11 职场文书
小学清明节活动方案
2014/03/08 职场文书
服装发布会策划方案
2014/05/22 职场文书
企业授权委托书范本
2014/09/22 职场文书
在职证明书模板
2015/06/15 职场文书
2016教师读书思廉心得体会
2016/01/23 职场文书
Golang标准库syscall详解(什么是系统调用)
2021/05/25 Golang
Python OpenCV超详细讲解读取图像视频和网络摄像头
2022/04/02 Python