浅析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 - HTML的request类
Jul 15 Javascript
datePicker——日期选择控件(with jquery)
Feb 20 Javascript
extjs grid设置某列背景颜色和字体颜色的方法
Sep 03 Javascript
js脚本获取webform服务器控件的方法
May 16 Javascript
微信公众号开发 实现点击返回按钮就返回到聊天界面
Dec 15 Javascript
微信小程序 详解下拉加载与上拉刷新实现方法
Jan 13 Javascript
vue父组件向子组件(props)传递数据的方法
Jan 02 Javascript
vue实现重置表单信息为空的方法
Sep 29 Javascript
javascript中的this作用域详解
Jul 15 Javascript
webpack 处理CSS资源的实现
Sep 27 Javascript
小程序中使用css var变量(使js可以动态设置css样式属性)
Mar 31 Javascript
vue中利用mqtt服务端实现即时通讯的步骤记录
Jul 01 Vue.js
在小程序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常用函数 推荐收藏保存
2010/02/21 PHP
getimagesize获取图片尺寸实例
2014/11/15 PHP
详谈PHP编码转换问题
2015/07/28 PHP
thinkPHP实现将excel导入到数据库中的方法
2016/04/22 PHP
php类的自动加载操作实例详解
2016/09/28 PHP
PHP实现的mysql操作类【MySQL与MySQLi方式】
2017/10/07 PHP
浅析PHP数据导出知识点
2018/02/17 PHP
PHP实现的简单路由和类自动加载功能
2018/03/13 PHP
将Datatable转化成json发送前台实现思路
2013/09/06 Javascript
弹出窗口并且此窗口带有半透明的遮罩层效果
2014/03/13 Javascript
JavaScript中的值是按值传递还是按引用传递问题探讨
2015/01/30 Javascript
js选项卡的实现方法
2015/02/09 Javascript
js实现input框文字动态变换显示效果
2015/08/19 Javascript
NodeJS设计模式总结【单例模式,适配器模式,装饰模式,观察者模式】
2017/09/06 NodeJs
Windows下Node.js安装及环境配置方法
2017/09/18 Javascript
layui的面包屑或者表单不显示的解决方法
2019/09/05 Javascript
Element Badge标记的使用方法
2020/07/27 Javascript
Python实现大文件排序的方法
2015/07/10 Python
Python通过90行代码搭建一个音乐搜索工具
2015/07/29 Python
tensorflow学习教程之文本分类详析
2018/08/07 Python
PyTorch基本数据类型(一)
2019/05/22 Python
python实现批量文件重命名
2019/10/31 Python
wxpython多线程防假死与线程间传递消息实例详解
2019/12/13 Python
如何解决tensorflow恢复模型的特定值时出错
2020/02/06 Python
Araks官网:纽约内衣品牌
2020/10/15 全球购物
行政部总经理岗位职责
2014/01/04 职场文书
全国道德模范事迹
2014/02/01 职场文书
护士岗位职责
2014/02/16 职场文书
信息服务专业毕业生求职信
2014/03/02 职场文书
庆祝国庆节标语
2014/10/09 职场文书
幼儿园大班个人总结
2015/02/28 职场文书
土木工程生产实习心得体会
2016/01/22 职场文书
使用Python脚本对GiteePages进行一键部署的使用说明
2021/05/27 Python
使用python+pygame开发消消乐游戏附完整源码
2021/06/10 Python
Java 超详细讲解IO操作字节流与字符流
2022/03/25 Java/Android
PostgreSQL并行计算算法及参数强制并行度设置方法
2022/04/07 PostgreSQL