浅析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的IE和Firefox兼容性汇编
Jul 01 Javascript
node.js中的fs.link方法使用说明
Dec 15 Javascript
js实现横向百叶窗效果网页切换动画效果的方法
Mar 02 Javascript
JScript中的条件注释详解
Apr 24 Javascript
JavaScript实现自动变换表格边框颜色
May 08 Javascript
使用AngularJS实现可伸缩的页面切换的方法
Jun 19 Javascript
js两种拼接字符串的简单方法(必看)
Sep 02 Javascript
Bootstrap基本布局实现方法详解
Nov 25 Javascript
深入浅析AngularJS中的一次性数据绑定 (bindonce)
May 11 Javascript
基于AngularJS的拖拽文件上传的实例代码
Jul 15 Javascript
Vue通过WebSocket建立长连接的实现代码
Nov 05 Javascript
js判断一个对象是数组(函数)的方法实例
Dec 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
在PHP3中实现SESSION的功能(三)
2006/10/09 PHP
利用curl 多线程 模拟 并发的详解
2013/06/14 PHP
完整删除ecshop中获取店铺信息的API
2014/12/24 PHP
PHP实现导出带样式的Excel
2016/08/28 PHP
PHP实现蛇形矩阵,回环矩阵及数字螺旋矩阵的方法分析
2017/05/29 PHP
浅谈laravel orm 中的一对多关系 hasMany
2019/10/21 PHP
js字符编码函数区别分析
2008/06/05 Javascript
9个JavaScript评级/投票插件
2010/01/18 Javascript
javascript中的变量是传值还是传址的?
2010/04/19 Javascript
Javascript 面向对象(一)(共有方法,私有方法,特权方法)
2012/05/23 Javascript
jquery $.trim()方法使用介绍
2014/05/21 Javascript
javascript移动开发中touch触摸事件详解
2016/03/18 Javascript
Node.js读写文件之批量替换图片的实现方法
2016/09/07 Javascript
jQuery is not defined 错误原因与解决方法小结
2017/03/19 Javascript
VueJs 搭建Axios接口请求工具
2017/11/20 Javascript
微信小程序左滑删除功能开发案例详解
2018/11/12 Javascript
Element输入框带历史查询记录的实现示例
2019/01/15 Javascript
如何实现双向绑定mvvm的原理实现
2019/05/28 Javascript
JavaScript实现轮播图效果
2020/10/30 Javascript
python中urllib模块用法实例详解
2014/11/19 Python
Python使用迭代器打印螺旋矩阵的思路及代码示例
2016/07/02 Python
Python实现树的先序、中序、后序排序算法示例
2017/06/23 Python
详解Python 序列化Serialize 和 反序列化Deserialize
2017/08/20 Python
Python学习pygal绘制线图代码分享
2017/12/09 Python
python判断列表的连续数字范围并分块的方法
2018/11/16 Python
Python3 用matplotlib绘制sigmoid函数的案例
2020/12/11 Python
python 基于DDT实现数据驱动测试
2021/02/18 Python
webView加载html图片遇到的问题解决
2019/10/08 HTML / CSS
The North Face北面英国官网:美国著名户外品牌
2017/12/13 全球购物
简述网络文件系统NFS,并说明其作用
2016/10/19 面试题
安全资料员岗位职责
2013/12/14 职场文书
《鸿门宴》教学反思
2014/04/22 职场文书
十佳护士先进事迹
2014/05/08 职场文书
幸福家庭事迹材料
2014/12/20 职场文书
史上最全书信经典范文大全(建议收藏)
2019/07/10 职场文书
nginx rewrite功能使用场景分析
2022/05/30 Servers