视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
js中什么是自定义react数据验证组件(详解)
2020-11-27 19:29:49 责编:小采
文档


本篇文章给大家带来的内容是介绍什么是自定义react数据验证组件。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所助。

我们在做前端表单提交时,经常会遇到要对表单中的数据进行校验的问题。如果用户提交的数据不合法,例如格式不正确、非数字类型、超过最大长度、是否必填项、最大值和最小值等等,我们需要在相应的地方给出提示信息。如果用户修正了数据,我们还要将提示信息隐藏起来。

有一些现成的插件可以让你非常方便地实现这一功能,如果你使用的是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;
    }

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

    下载本文
    显示全文
    专题