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()方法中加入该组件的引用:

<div className="item">
  <div className="col-xs-4">净车价:</div>
  <div 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"/>
  </div>
  <div className="col-xs-1 text-center">元</div>
  <div className="clear"></div>
</div>

我们将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;
}

 

这样,我们在父组件提交数据之前,可以通过这个方法来判断所有的数据项是否都已经通过验证,如果未通过验证,则不提交表单。

其它几个基于React的数据验证组件,不过貌似都是server端使用的:

https://github.com/edwardfhsiao/react-inputs-validation

https://github.com/learnetto/react-form-validation-demo

https://learnetto.com/blog/how-to-do-simple-form-validation-in-reactjs

总结

以上所述是小编给大家介绍的js中自定义react数据验证组件实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jquery实现隐藏与显示动画效果/输入框字符动态递减/导航按钮切换
Jul 01 Javascript
JQuery实现带排序功能的权限选择实例
May 18 Javascript
JavaScript实现获得所有兄弟节点的方法
Jul 23 Javascript
JS简单循环遍历json数组的方法
Apr 22 Javascript
JS中常用的输出方式(五种)
Jun 12 Javascript
浅谈JavaScript中的this指针和引用知识
Aug 05 Javascript
JS制作适用于手机和电脑的通知信息效果
Oct 28 Javascript
JQueryEasyUI之DataGrid数据显示
Nov 23 Javascript
Node.JS 循环递归复制文件夹目录及其子文件夹下的所有文件
Sep 18 Javascript
解决webpack dev-server不能匹配post请求的问题
Aug 24 Javascript
微信小程序 wx.getUserInfo引导用户授权问题实例分析
Mar 09 Javascript
LayUI+Shiro实现动态菜单并记住菜单收展的示例
May 06 Javascript
值得收藏的八个常用的js正则表达式
Oct 19 #Javascript
深入理解移动前端开发之viewport
Oct 19 #Javascript
vue移动端html5页面根据屏幕适配的四种解决方法
Oct 19 #Javascript
Vue用v-for给循环标签自身属性添加属性值的方法
Oct 18 #Javascript
vue中v-for循环给标签属性赋值的方法
Oct 18 #Javascript
webstorm+vue初始化项目的方法
Oct 18 #Javascript
使用微信小程序开发弹出框应用实例详解
Oct 18 #Javascript
You might like
杏林同学录(四)
2006/10/09 PHP
通俗易懂的php防注入代码
2010/04/07 PHP
30 个很棒的PHP开源CMS内容管理系统小结
2011/10/14 PHP
深入解读php中关于抽象(abstract)类和抽象方法的问题分析
2014/01/03 PHP
推荐一款PHP+jQuery制作的列表分页的功能模块
2014/10/14 PHP
thinkphp实现分页显示功能
2016/12/03 PHP
HTML5如何适配 iPhone IOS 底部黑条
2021/03/09 HTML / CSS
Aster vs KG BO3 第二场2.19
2021/03/10 DOTA
基于JQuery实现滚动到页面底端时自动加载更多信息
2014/01/31 Javascript
使用jquery实现IE下按backspace相当于返回操作
2014/03/18 Javascript
基于Jquery实现键盘按键监听
2014/05/11 Javascript
DOM基础教程之使用DOM控制表单
2015/01/20 Javascript
Javascript实现快速排序(Quicksort)的算法详解
2015/09/06 Javascript
浅谈js中test()函数在正则中的使用
2016/08/19 Javascript
Node.js之网络通讯模块实现浅析
2017/04/01 Javascript
JavaScript中click和onclick本质区别与用法分析
2018/06/07 Javascript
如何制作一个Node命令行图像识别工具
2018/12/12 Javascript
详解使用JWT实现单点登录(完全跨域方案)
2019/08/02 Javascript
JavaScript设计模式之门面模式原理与实现方法分析
2020/03/09 Javascript
Echarts在Taro微信小程序开发中的踩坑记录
2020/11/09 Javascript
使用jquery实现轮播图效果
2021/01/02 jQuery
Python中多线程的创建及基本调用方法
2016/07/08 Python
pandas pivot_table() 按日期分多列数据的方法
2018/11/16 Python
Windows下Python3.6安装第三方模块的方法
2018/11/22 Python
Python对excel文档的操作方法详解
2018/12/10 Python
Python实现一个带权无回置随机抽选函数的方法
2019/07/24 Python
SHEIN台湾:购买最新流行女装服饰
2019/05/18 全球购物
Herschel美国官网:背包、手提袋及配件
2020/03/10 全球购物
标准化管理实施方案
2014/02/25 职场文书
计算机软件专业求职信
2014/06/10 职场文书
水污染治理工程专业求职信
2014/06/14 职场文书
个人师德师风自我剖析材料
2014/09/29 职场文书
房贷收入证明范本
2015/06/12 职场文书
python tkinter实现定时关机
2021/04/21 Python
深入探讨opencv图像矫正算法实战
2021/05/21 Python
使用compose函数优化代码提高可读性及扩展性
2022/06/16 Javascript