浅析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 实现菜单左右滚动显示示例介绍
Nov 21 Javascript
jQuery实现返回顶部功能适合不支持js的浏览器
Aug 19 Javascript
Javascript基础教程之JavaScript语法
Jan 18 Javascript
jQuery无刷新分页完整实例代码
Oct 27 Javascript
Vuejs第七篇之Vuejs过渡动画案例全面解析
Sep 05 Javascript
JS 终止执行的实现方法
Nov 24 Javascript
jQuery中select与datalist制作下拉菜单时的区别浅析
Dec 30 Javascript
Vue键盘事件用法总结
Apr 18 Javascript
初探JavaScript 面向对象(推荐)
Sep 03 Javascript
在layui中select更改后生效的方法
Sep 05 Javascript
JS script脚本中async和defer区别详解
Jun 24 Javascript
vue实现拖拽进度条
Mar 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的历史和优缺点
2006/10/09 PHP
深入讲解PHP的对象注入(Object Injection)
2017/03/01 PHP
在Mac OS下搭建LNMP开发环境的步骤详解
2017/03/10 PHP
JavaScript 格式字符串的应用
2010/03/29 Javascript
Textarea与懒惰渲染实现代码
2012/01/04 Javascript
jquery showModelDialog的使用方法示例详解
2013/11/19 Javascript
自定义jquery模态窗口插件无法在顶层窗口显示问题
2014/05/29 Javascript
js格式化输入框内金额、银行卡号
2016/02/01 Javascript
JavaScript实现简洁的俄罗斯方块完整实例
2016/03/01 Javascript
JavaScript高级程序设计(第三版)学习笔记6、7章
2016/03/11 Javascript
对jquery的ajax进行二次封装以及ajax缓存代理组件:AjaxCache详解
2016/04/11 Javascript
jquery easyui DataGrid简单示例
2017/01/23 Javascript
JS设计模式之访问者模式定义与用法分析
2018/02/05 Javascript
React 组件中的 bind(this)示例代码
2018/09/16 Javascript
详解Vue源码之数据的代理访问
2018/12/11 Javascript
JavaScript继承的特性与实践应用深入详解
2018/12/30 Javascript
vue-cli脚手架引入弹出层layer插件的几种方法
2019/06/24 Javascript
Nodejs实现图片上传、压缩预览、定时删除功能
2019/10/25 NodeJs
Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法
2015/05/22 Python
Python的Flask框架中使用Flask-SQLAlchemy管理数据库的教程
2016/06/14 Python
python安装numpy&amp;安装matplotlib&amp; scipy的教程
2017/11/02 Python
Python开发最牛逼的IDE——pycharm
2018/08/01 Python
使用python Telnet远程登录执行程序的方法
2019/01/26 Python
使用wxpy实现自动发送微信消息功能
2020/02/28 Python
Python的Django框架实现数据库查询(不返回QuerySet的方法)
2020/05/19 Python
css3中的calc函数浅析
2018/07/10 HTML / CSS
html5理解head_动力节点Java学院整理
2017/07/13 HTML / CSS
美国Rue La La闪购网站:奢侈品、中高档品牌限时折扣
2016/10/19 全球购物
英国文胸专家:AmpleBosom.com
2018/02/06 全球购物
优秀党员获奖感言
2014/02/18 职场文书
工作决心书
2014/03/11 职场文书
打架赔偿协议书范本
2014/10/26 职场文书
2014年环保局工作总结
2014/12/11 职场文书
python opencv常用图形绘制方法(线段、矩形、圆形、椭圆、文本)
2021/04/12 Python
详细聊聊关于Mysql联合查询的那些事儿
2021/10/24 MySQL
python lambda 表达式形式分析
2022/04/03 Python