動(dòng)機(jī)
當(dāng)我們使用 ElementUI 來做前端校驗(yàn)時(shí),大多數(shù)項(xiàng)目都不會(huì)被其自帶的簡單校驗(yàn)規(guī)則所滿足。所以我們經(jīng)常需要自定義校驗(yàn)函數(shù) validator 來滿足我們的項(xiàng)目需求。而這時(shí)又會(huì)出現(xiàn)一個(gè)比較棘手的問題:這個(gè)自定義的 validator 由于無法傳參,復(fù)用性極差。
比如我們上一篇文章做了一個(gè)自定義的中英文混合長度校驗(yàn)函數(shù):
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 個(gè)字符'))
}
}
詳情參見:Element UI 中文英文混合字符長度校驗(yàn)
這時(shí),有另一個(gè)表單想使用這個(gè)校驗(yàn)規(guī)則,但是要限制的長度不是 64 而是 128 。尷尬的事情發(fā)生了 —— 由于無法傳參,我們要把這個(gè)校驗(yàn)函數(shù)再寫一遍。如果還有 n 多個(gè)別的地方也想使用,我們是不是還要把這一串重復(fù)的代碼寫 n 遍呢?這顯然不是開發(fā)者們想要的。
場(chǎng)景
當(dāng)一套自定義校驗(yàn)規(guī)則適用于多個(gè)表單,只有參數(shù)不同時(shí)。
傳參的實(shí)現(xiàn)
傳參的目的無非是不同的調(diào)用者可以訪問到不同的數(shù)據(jù),所以當(dāng)普通的傳參無法實(shí)現(xiàn)時(shí),我們改變了思路:使用 bind 。
原理:不用的調(diào)用者調(diào)用函數(shù)時(shí),通過 bind 生成一個(gè)新的函數(shù),并改變其 this 的指向。
這時(shí),我們只需要在校驗(yàn)函數(shù)內(nèi)部使用 this 來獲取“參數(shù)”就好啦:
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} 個(gè)字符`))
}
}
const length32 = {
maxLength:32
}
const length64 = {
maxLength:256
}
使用時(shí):
//...
rules:{
name:[{
validator: validLength.bind(length32),
trigger: 'blur'
}],
address:[{
validator: validLength.bind(length256),
trigger: 'blur'
}]
}
//...
如此一來,我們就使用了一套校驗(yàn)規(guī)則對(duì)多個(gè)表單進(jìn)行了限制,并且達(dá)到了靈活的傳參效果。