ElementUI 的校验函数 validator 的传参与复用

动机

当我们使用 ElementUI 来做前端校验时,大多数项目都不会被其自带的简单校验规则所满足。所以我们经常需要自定义校验函数 validator 来满足我们的项目需求。而这时又会出现一个比较棘手的问题:这个自定义的 validator 由于无法传参,复用性极差。

比如我们上一篇文章做了一个自定义的中英文混合长度校验函数:

const validLength = function (rule, value, callback) {
    function getStrLength(str) {
        return str.replace(/[^x00-xff]/g, 'xxx').length;
    }
    if (!value) {
        callback();
    } else if (getStrLength(value) <= 64) {
        callback();
    } else {
        return callback(new Error('不能超过 64 个字符'))
    }
}

详情参见:Element UI 中文英文混合字符长度校验

这时,有另一个表单想使用这个校验规则,但是要限制的长度不是 64 而是 128 。尴尬的事情发生了 —— 由于无法传参,我们要把这个校验函数再写一遍。如果还有 n 多个别的地方也想使用,我们是不是还要把这一串重复的代码写 n 遍呢?这显然不是开发者们想要的。

场景

当一套自定义校验规则适用于多个表单,只有参数不同时。

传参的实现

传参的目的无非是不同的调用者可以访问到不同的数据,所以当普通的传参无法实现时,我们改变了思路:使用 bind

原理:不用的调用者调用函数时,通过 bind 生成一个新的函数,并改变其 this 的指向。

这时,我们只需要在校验函数内部使用 this 来获取“参数”就好啦:

const validLength = function (rule, value, callback) {
    function getStrLength(str) {
        return str.replace(/[^x00-xff]/g, 'xxx').length;
    }
    if (!value) {
        callback();
    } else if (getStrLength(value) <= this.maxLength) {
        callback();
    } else {
        return callback(new Error(`不能超过 ${this.maxLength} 个字符`))
    }
}

const length32 = {
    maxLength:32
}
const length64 = {
    maxLength:256
}

使用时:

//...
rules:{
    name:[{
        validator: validLength.bind(length32),
        trigger: 'blur'
    }],
    address:[{
        validator: validLength.bind(length256),
        trigger: 'blur'
    }]
}
//...

如此一来,我们就使用了一套校验规则对多个表单进行了限制,并且达到了灵活的传参效果。

你可能感兴趣的:(vue,vue,elementui)