摘要:一表單驗(yàn)證模塊的構(gòu)成任何表單驗(yàn)證模塊都是由配置校驗(yàn)報(bào)錯(cuò)取值這幾部分構(gòu)成的。其實(shí)我是想寫個(gè)指令來(lái)完成表單驗(yàn)證的事的。當(dāng)然表單驗(yàn)證這種是高度定制化的。
前言
前段時(shí)間,老大搭好了Vue的開(kāi)發(fā)環(huán)境,于是我們愉快地從JQ來(lái)到了Vue。這中間做的時(shí)候,在表單驗(yàn)證上做的不開(kāi)心,看到vue的插件章節(jié),感覺(jué)自己也能寫一個(gè),因此就自己開(kāi)始寫了一個(gè)表單驗(yàn)證插件va.js。
當(dāng)然為什么不找個(gè)插件呢? vue-validator呀。
我想了下,一個(gè)是表單驗(yàn)證是個(gè)高度定制化的東西,這種網(wǎng)上找到的插件為了兼顧各個(gè)公司的需求,所以加了很多功能,這些我們不需要。事實(shí)證明,vue-validator有50kb,而我寫的va.js只有8kb。
另一個(gè)是,vue-validator的api我真的覺(jué)得長(zhǎng), 動(dòng)不動(dòng)就v-validate:username="["required"]",這么一長(zhǎng)串,而我設(shè)計(jì)的調(diào)用大概如——v-va:Money
當(dāng)然,本文僅是展示下,如何寫個(gè)滿足自己公司需求的vue表單驗(yàn)證插件。下面介紹下思路。
一、表單驗(yàn)證模塊的構(gòu)成任何表單驗(yàn)證模塊都是由 配置——校驗(yàn)——報(bào)錯(cuò)——取值 這幾部分構(gòu)成的。
配置: 配置規(guī)則 和配置報(bào)錯(cuò),以及優(yōu)先級(jí)
校驗(yàn): 有在 change 事件校驗(yàn), 在點(diǎn)擊提交按鈕的時(shí)候校驗(yàn), 當(dāng)然也有在input事件取值的
報(bào)錯(cuò): 報(bào)錯(cuò)方式一般要分,報(bào)錯(cuò)的文字有模板,也有自定義的
取值: 將通過(guò)驗(yàn)證的數(shù)據(jù)返還給開(kāi)發(fā)者調(diào)用
下面是我老大針對(duì)公司項(xiàng)目給我提出的要求
集中式的管理 校驗(yàn)規(guī)則 和 報(bào)錯(cuò)模板。
報(bào)錯(cuò)時(shí)機(jī)可選
校驗(yàn)正確后的數(shù)據(jù),已經(jīng)打包成對(duì)象,可以直接用
允許各個(gè)頁(yè)面對(duì)規(guī)則進(jìn)行覆蓋,對(duì)報(bào)錯(cuò)信息進(jìn)行自定義修改,以及允許ajax獲取數(shù)據(jù)后,再對(duì)規(guī)則進(jìn)行補(bǔ)充
按順序來(lái)校驗(yàn),在第一個(gè)報(bào)錯(cuò)的框彈出錯(cuò)誤
我就很好奇地問(wèn), 為什么要這樣子呢?然后老大就跟我一條一條解答:
集中式管理規(guī)則,和報(bào)錯(cuò)模板的好處,就是規(guī)則可以全局通用,一改全改。老大跟我說(shuō),光是昵稱的正則就改了三次。如果這些正則寫在各個(gè)頁(yè)面,o( ̄ヘ ̄o#)哼,你就要改N個(gè)頁(yè)面了
pc和移動(dòng)的流程不一樣,pc很多校驗(yàn)都要在change事件或者input事件就校驗(yàn)并報(bào)錯(cuò)了,而移動(dòng)則一般是要到提交按鈕再進(jìn)行校驗(yàn)。所以寫插件的時(shí)候要做好兩手準(zhǔn)備。然后,報(bào)錯(cuò)用的ui要可以支持我們現(xiàn)在用的layer插件。當(dāng)然以后這個(gè)報(bào)錯(cuò)的ui也可能變,所以你懂滴。
當(dāng)然原來(lái)jq時(shí)代,我們的公用表單驗(yàn)證,就能驗(yàn)證完了,把數(shù)據(jù)都集合到一個(gè)對(duì)象里。這樣ajax的時(shí)候,就不用再去取值了。你這個(gè)插件耶要達(dá)到這個(gè)效果
原來(lái)jq的那個(gè)公用腳本,正則和報(bào)錯(cuò)都集中到一個(gè)地方去了,在很多地方已經(jīng)很方便了。但是在一些頁(yè)面需要改東西的時(shí)候還不夠靈活。像RealName這個(gè)規(guī)則,最早是針對(duì)某個(gè)頁(yè)面配置的,用的是后端接口上的字段名。另一個(gè)支付頁(yè),后端接口上的字段名改成了PayUser了,但是正則還是RealName的,原來(lái)我們是要復(fù)寫一下RealName。這個(gè)就不太方便也不好看了。另外一個(gè),支付金額,有最大值和最小值的限制,這個(gè)需要從后端獲取的。你也要考慮這個(gè)情況。要做到各個(gè)頁(yè)面上也能有一些靈活的地方可以修改規(guī)則,自定義報(bào)錯(cuò)等等。
為什么要按順序校驗(yàn)啊?你忘了上次牛哥讓我們輸入框,從上到下,按順序報(bào)錯(cuò)。不然用戶都不知道哪個(gè)地方錯(cuò)了。還有規(guī)則也是要按順序的。哦哦哦。看來(lái)這次我放東西的時(shí)候,要用下數(shù)組了。盡量保持順序。
我聽(tīng)了之后,大致懂了,原來(lái)之前自己寫的jq表單驗(yàn)證還有這么多不舒服的點(diǎn)。-_-|||
接下來(lái),是看看vue給我的好東西。讓我來(lái)寫
我一個(gè)vue小白,怎么就開(kāi)始寫vue插件了呢?那是因?yàn)橄虢鉀Q方案的時(shí)候,翻Vue文檔翻到了這里
這些東東,等我寫完va.js的時(shí)候,感覺(jué)尤大寫的真的是很清楚了。
其實(shí)我是想寫個(gè)指令來(lái)完成表單驗(yàn)證的事的。結(jié)果發(fā)現(xiàn)可能有2-3個(gè)指令,而且要再Vue.prototype上定義些方法,好讓各個(gè)子實(shí)例內(nèi)部也能拓展規(guī)則。于是老大說(shuō),這就相當(dāng)于插件了。這讓我很是吃鯨。
va.js主要用的是 Vue指令Vue 文檔真的寫得很用心,但是我再補(bǔ)充一點(diǎn)吧
vnode.context 就是Vue的實(shí)例
我們做項(xiàng)目的時(shí)候,經(jīng)常一個(gè)根組件上掛著N個(gè)子組件,子組件上又可能掛著N個(gè)子組件。vnode.context獲取的實(shí)例,是綁定該指令的組件的實(shí)例。這個(gè)就相當(dāng)好用了。你可以做很多事情
Vue.prototype.$method 就是可以在各個(gè)組件上調(diào)用的方法??梢栽诮M件內(nèi)部用 this.$method調(diào)用的
## 三、具體實(shí)現(xiàn)的思路 ##
核心思路如下圖:
規(guī)則的構(gòu)造函數(shù)
//va配置的構(gòu)造函數(shù) function VaConfig(type, typeVal, errMsg, name, tag){ this.type = type, this.typeVal = typeVal, this.errMsg = errMsg, this.name = name, this.tag = tag }
type: nonvoid(非空), reg(正則), limit(區(qū)間), equal(與某個(gè)input相等),unique(不能相同)
typeVal: 根據(jù)不同type設(shè)置不同的值
errMsg: 自定義的報(bào)錯(cuò)信息
name: 用來(lái)傳ajax的字段,如Password, Username
tag:用來(lái)報(bào)錯(cuò)的名字,如‘銀行賬號(hào)’,‘姓名’
設(shè)置了三種規(guī)則1.默認(rèn)規(guī)則: 只要綁定指令,就默認(rèn)有的校驗(yàn)。 比如非空的校驗(yàn)。 可以額外加修飾符來(lái)去除
2.選項(xiàng)規(guī)則: 通過(guò)Vue指令的修飾符添加的規(guī)則。
3.自定義規(guī)則: Vue指令屬性值上添加的規(guī)則。
同一個(gè)type的規(guī)則只存在一個(gè),也就是說(shuō),如果type為reg(正則),那么會(huì)互相覆蓋。
覆蓋的優(yōu)先級(jí): 自定義規(guī)則 > 選項(xiàng)規(guī)則 > 默認(rèn)規(guī)則
思路講的多了。也不知道怎么講了,下面大家直接看源碼把。
源碼var Vue var checkWhenChange = true //每個(gè)輸入框需要離焦即校驗(yàn) // 給一個(gè)dom添加class function addClass(dom, className){ // if (dom.classList){ // dom.classList.add(className); // }else{ // dom.className += " " + className; // } var hasClass = !!dom.className.match(new RegExp("(s|^)" + _class + "(s|$)")) if(!hasClass){ dom.className += " " + _class } } //常用正則表 var regList = { ImgCode: /^[0-9a-zA-Z]{4}$/, SmsCode: /^d{4}$/, MailCode: /^d{4}$/, UserName: /^[w|d]{4,16}$/, Password: /^[w!@#$%^&*.]{6,16}$/, Mobile: /^1[3|4|5|7|8]d{9}$/, RealName: /^[u4e00-u9fa5|·]{2,16}$|^[a-zA-Z|s]{2,20}$/, BankNum: /^d{10,19}$/, Money: /^([1-9]d*|[0-9]d*.d{1,2}|0)$/, Answer: /^S+$/, Mail: /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/ } // 斷言函數(shù) function assert(condition, message){ if(!condition){ console.error("[va-warn]:" + message) } } // Rule構(gòu)造器 function Rule(ruleType, ruleValue, errMsg){ this.ruleType = ruleType this.ruleValue = ruleValue this.errMsg = errMsg || "" } //VaForm構(gòu)造器 function VaForm(el, finalRules, modifiers){ this.ruleOrder = [] this.rules = {} this.dom = el this.value = el.value //值的副本 this.validated = false //是否被驗(yàn)證過(guò) this.tag = el.getAttribute("tag") //提示的字段名 // this.correctMsg = `${this.tag}輸入正確!` this.correctMsg = "" this.modifiers = modifiers //一些特殊的配置 this.noCheck = false //為true則不要校驗(yàn) this.ruleOrder = finalRules.map(item=>{ this.rules[item.ruleType] = item return item.ruleType }) } //rules中靠前的配置優(yōu)先級(jí)最高 function mergeRule(...rules){ var mergeResult = [] var combineArr = Array.prototype.concat.apply([], rules) var hash = {} combineArr.forEach((rule)=>{ if(hash[rule.ruleType] === undefined){ mergeResult.push(rule) hash[rule.ruleType] = mergeResult.length - 1 }else{ var index = hash[rule.ruleType] Object.assign(mergeResult[index], rule) } }) return mergeResult } //單個(gè)規(guī)則的驗(yàn)證結(jié)果 function VaResult(ruleType, ruleValue, isPass, errMsg){ this.ruleType = ruleType this.ruleValue = ruleValue this.isPass = isPass this.errMsg = errMsg } // 顯示結(jié)果的構(gòu)造器 function DisplayResult(isPass, message){ this.isPass = isPass this.message = message } //單個(gè)規(guī)則的校驗(yàn),或者單個(gè)表單的校驗(yàn) function validate(field, ruleType){ assert(field, "未輸入要驗(yàn)證的字段") var vaForm = this.forms[field] var {ruleOrder, rules} = vaForm if(ruleType === undefined){ return this.checkForm(vaForm) }else{ var rule = rules[ruleType] //規(guī)則 return this.checkRule(vaForm, rule) } // vaForm.validated = true } // 獲得不同的報(bào)錯(cuò)信息 function getErrMsg(vaForm, ruleType, ruleValue){ var tag = vaForm.tag var errMsgs = { NonEmpty: `${tag}不能為空`, reg: `${tag}格式錯(cuò)誤`, limit: `${tag}必須在${ruleValue[0]}與${ruleValue[1]}之間`, equal:`兩次${tag}不相同`, length: `${tag}長(zhǎng)度必須在${ruleValue[0]}與${ruleValue[1]}之間`, unique: `${tag}不能相同` } return errMsgs[ruleType] } //檢測(cè)非空 function checkEmpty(ruleValue, vaForm, va){ return vaForm.value.trim() ? true : false } //檢測(cè)正則 function checkReg(ruleValue, vaForm, va){ return ruleValue.test(vaForm.value) ? true : false } //檢測(cè)數(shù)字區(qū)間 function checkLimit(ruleValue, vaForm, va){ var value = vaForm.value return ((+value >= ruleValue[0]) && (+value <= ruleValue[1])) ? true : false } //檢測(cè)相等 function checkEqual(ruleValue, vaForm, va){ var target = va.forms[ruleValue] return target.value === vaForm.value ? true : false } //檢測(cè)字符長(zhǎng)度 function checkCharLength(ruleValue, vaForm, va){ var length = vaForm.value.length return ((+length >= ruleValue[0]) && (+length <= ruleValue[1])) ? true : false } //幾個(gè)輸入框要各不相同 function checkUnique(ruleValue, vaForm, va){ var uniqueGroup = va.uniqueGroup[ruleValue] var values = uniqueGroup.map(field=>va.forms[field].value) var uniqueValues = values.filter((item,index,arr)=>arr.indexOf(item) === index) return values.length === uniqueValues.length ? true : false } // 檢測(cè)單個(gè)規(guī)則 function checkRule(vaForm, rule){ var forms = this.forms var {ruleType, ruleValue, errMsg} = rule //如果有自定義報(bào)錯(cuò)就按自定義報(bào)錯(cuò),沒(méi)有就格式化報(bào)錯(cuò) errMsg = errMsg || getErrMsg(vaForm, ruleType, ruleValue) var ruleCheckers = { NonEmpty: checkEmpty, reg: checkReg, limit: checkLimit, equal: checkEqual, length: checkCharLength, unique: checkUnique } var ruleChecker = ruleCheckers[ruleType] var isPass = ruleChecker(ruleValue, vaForm, this) var vaResult = new VaResult(ruleType, ruleValue, isPass, isPass ? null : errMsg) return vaResult } //檢測(cè)單個(gè)表單 function checkForm(vaForm){ var results = vaForm.ruleOrder.map(ruleType=>{ var rule = vaForm.rules[ruleType] return this.checkRule(vaForm,rule) }) var errIndex = null for(var i = 0;i < results.length;i++){ var result = results[i] if(result.isPass === false){ errIndex = i break } } if(errIndex === null){ return new DisplayResult(true, vaForm.correctMsg) }else{ return new DisplayResult(false, results[errIndex].errMsg) } } //刷新vaForm中的值的數(shù)據(jù) function refreshValue(field, newValue){ this.forms[field].value = newValue + "" } //更新所有表單的值 function refreshAllValue(){ this.fieldOrder.forEach(field=>{ var vaForm = this.forms[field] vaForm.value = vaForm.dom.value }) } // 校驗(yàn)所有的表單,并彈出第一個(gè)錯(cuò)誤??紤]可以為空的情況 function checkAll(){ var firstErr = null this.fieldOrder.forEach(field=>{ var vaForm = this.forms[field] var canNull = vaForm.ruleOrder.every(ruleType=>ruleType !== "NonEmpty") //輸入框可以為空 var noCheckEmpty = (vaForm.value === "" && canNull) //該輸入框可以為空,且輸入為空 if(vaForm.noCheck === false && noCheckEmpty === false){ var result = this.setVmResult(field) // var result = this.validate(field) // this.vmResult[field] = result // vaForm.validated = true if(firstErr === null && result.isPass === false){ firstErr = result.message } } }) return firstErr } //驗(yàn)證單個(gè)字段,返回值,并彈出報(bào)錯(cuò) function setVmResult(field){ var result = this.validate(field) //本輸入框結(jié)果 this.vmResult[field] = result //將報(bào)錯(cuò)彈出 this.forms[field].validated = true //校驗(yàn)過(guò)了 return result } // 返回各個(gè)表單的值對(duì)象 function getValue(){ var dataSet = {} for(var field in this.forms){ dataSet[field] = this.forms[field].value } return dataSet } //添加一個(gè)規(guī)則 function addRule(field, index, Rule){ var vaForm = this.forms[field] vaForm.ruleOrder.splice(index, 0, Rule.ruleType) vaForm.rules[Rule.ruleType] = Rule } // function resetAll(){ // this.fieldOrder.forEach(field=>{ // this.refreshValue(field, "") // }) // } // 設(shè)置不校驗(yàn)的表單 function setNoCheck(field, bool){ this.forms[field].noCheck = bool } function createVa(vm, field){ var va = { vmResult:vm.va, fieldOrder:[], forms:{}, group:{ base:[], }, equalGroup:{}, //必須相等的字段 uniqueGroup:{}, //必須不同的字段 Rule:Rule, //Rule構(gòu)造器 VaForm:VaForm, //VaForm構(gòu)造器 validate: validate, //暴露的校驗(yàn)函數(shù) setVmResult: setVmResult, //校驗(yàn)并報(bào)錯(cuò) checkRule: checkRule, //內(nèi)部的校驗(yàn)單條規(guī)則的函數(shù) checkForm: checkForm, //內(nèi)部的校驗(yàn)單個(gè)表單的函數(shù) refreshValue: refreshValue, //更新某個(gè)表單的值 checkAll: checkAll, //檢查所有的函數(shù) getValue: getValue, //獲取所有表單的當(dāng)前值,得到一個(gè)對(duì)象 setNoCheck:setNoCheck, //設(shè)置為不校驗(yàn) addRule:addRule, //給一個(gè)表單添加一個(gè)規(guī)則 refreshAllValue:refreshAllValue //更新所有表單的值 // resetAll: resetAll } if(vm.$va){ return vm.$va }else{ vm.$va = va return va } } //v-va:Password.canNull = "[{reg:/^d{4}$/}]" //arg = Password, modifiers.canNull = true, value為后面相關(guān)的 //arg用來(lái)存字段名, modifiers用來(lái)存特殊配置, value為規(guī)則, tag是中文提示名, group 為分組 var main = {} main.install = function(_Vue, options){ Vue = _Vue Vue.directive("va",{ bind:function(el, binding, vnode){ var vm = vnode.context //當(dāng)前的vue實(shí)例 var field = binding.arg === "EXTEND" ? el.getAttribute("name") : binding.arg // 當(dāng)arg為EXTEND,從name屬性獲得值 var option = binding.modifiers //特殊配置(允許非空,編輯新增共用等) var value = el.value //輸入框的初始值 var group = el.getAttribute("group") || "base" //分組,一個(gè)表單框在多個(gè)組呢?這個(gè)還沒(méi)設(shè),要兼容。 通過(guò)類似 "group1 group2 group3 group4" var tag = el.getAttribute("tag") var regMsg = el.getAttribute("regMsg") || "" //針對(duì)正則的自定義報(bào)錯(cuò) var baseRule = [] //默認(rèn)的校驗(yàn)規(guī)則 --不用寫,默認(rèn)存在的規(guī)則(如非空),優(yōu)先級(jí)最高 var customRule = [] //用戶自定義的規(guī)則(組件中) --bingding.value var optionalRule = [] //配置項(xiàng)中引申出來(lái)的規(guī)則,優(yōu)先級(jí)最低 assert(tag, "未設(shè)置輸入框的tag") assert(vm.va, "實(shí)例的data選項(xiàng)上,未設(shè)置va對(duì)象") //實(shí)例上如果沒(méi)有設(shè)置結(jié)果則報(bào)錯(cuò)。 assert(field, "未設(shè)置輸入框字段") var va = createVa(vm, field) //單例模式創(chuàng)建va,綁定在vm上 va.fieldOrder.push(field) //字段的檢驗(yàn)順序 va.group[group].push(field) //分組 var NonEmpty = new Rule("NonEmpty", true, "") //默認(rèn)非空 if(option.CanNull === undefined){ baseRule.push(NonEmpty) } //如果regList里有name對(duì)應(yīng)的,直接就加進(jìn)optionalConfig if(regList[field]){ optionalRule.push(new Rule("reg", regList[field], regMsg)) } //如果modefiers中的字段有在正則表里,將其加入optionalRule var regOptions = Object.keys(option); for(var i = 0;i < regOptions.length;i++){ var regOption = regOptions[i] if(regList[regOptions[i]]){ optionalRule.push(new Rule("reg", regList[regOption], regMsg)) } } //用戶自定義的規(guī)則 if(binding.value !== undefined){ customRule = binding.value.map(item=>{ var ruleType = Object.keys(item)[0]; var errMsg = ruleType === "reg" ? regMsg : "" return new Rule(ruleType, item[ruleType], errMsg) }) } var finalRules = mergeRule(baseRule, optionalRule, customRule) var hasUniqueRule = false //對(duì)聯(lián)合校驗(yàn)的進(jìn)行預(yù)處理 finalRules.forEach(rule=>{ var {ruleType, ruleValue} = rule if(ruleType === "equal"){ if(va.equalGroup[ruleValue] === undefined){ va.equalGroup[ruleValue] = [field] }else{ va.equalGroup[ruleValue].push(field) } } if(ruleType === "unique"){ hasUniqueRule = ruleValue if(va.uniqueGroup[ruleValue] === undefined){ va.uniqueGroup[ruleValue] = [field] }else{ va.uniqueGroup[ruleValue].push(field) } } }) var vaForm = new VaForm(el, finalRules, option) va.forms[field] = vaForm if(checkWhenChange){ function validateSingle(){ va.refreshValue(field, el.value) //更新值 //如果允許為空的此時(shí)為空,不校驗(yàn) if(vaForm.value === "" && option.CanNull){ va.vmResult[field] = {} //如果為空,把界面顯示上面的提示清掉 return } if(vaForm.noCheck === false){ va.setVmResult(field) } var isEqualTarget = false for(var index in va.equalGroup){ if(index === field){ isEqualTarget = true } } //相等框的聯(lián)合校驗(yàn) if(isEqualTarget){ va.equalGroup[field].forEach(item=>{va.setVmResult(item)}) } //不同框的聯(lián)合校驗(yàn) if(hasUniqueRule){ va.uniqueGroup[hasUniqueRule].forEach(item=>{va.setVmResult(item)}) } } //在change和blur上都綁定了處理事件 el.addEventListener("change", validateSingle) el.addEventListener("blur", validateSingle) } }, }) } export default main
現(xiàn)在項(xiàng)目已經(jīng)用起來(lái)了。當(dāng)然表單驗(yàn)證這種是高度定制化的。純粹分享個(gè)過(guò)程和思路。也算我這個(gè)vue新手的一次階段性成果吧。哈哈~
使用實(shí)例第一個(gè)框,加了兩條指令
v-va:Password 這個(gè)代表使用配置表中password對(duì)應(yīng)的配置(包括非空和正則,默認(rèn)規(guī)則),同時(shí)應(yīng)用Password作為校驗(yàn)成功獲取的 數(shù)據(jù)對(duì)象的key
tag為報(bào)錯(cuò)顯示中此輸入框的名字
第二個(gè)框,為確認(rèn)框,也加了兩個(gè)指令
1.v-va:checkPassword.Password = "[{"equal":"Password"}]"
一般v-va后面的第一個(gè)字段為數(shù)據(jù)對(duì)象的key,他和正則對(duì)應(yīng)的名字有可能不同。
這個(gè)字段如果和配置表中的配置匹配,那么自然應(yīng)用配置。
如果不匹配,就要自己在后面用.的方式加配置(選項(xiàng)規(guī)則)。像這里的Password。
最后面還有一個(gè) 屬性值 "[{"equal":"Password"}]"(自定義規(guī)則)。
這個(gè)地方用了數(shù)組,即會(huì)按這個(gè)數(shù)組的配置來(lái)進(jìn)行校驗(yàn)。
同時(shí)這個(gè)數(shù)組有順序,順序代表規(guī)則的優(yōu)先級(jí)。
這個(gè)配置代表,這個(gè)框必須和上面那個(gè)Password的框值相等,否則報(bào)錯(cuò)。
另外確認(rèn)框不加入最后的結(jié)果數(shù)據(jù)對(duì)象。
2.tag 用來(lái)作為報(bào)錯(cuò)信息的名字
校驗(yàn)觸發(fā)按鈕 上面有一個(gè)指令 v-va-check
1.用來(lái)觸發(fā)校驗(yàn)
2.校驗(yàn)成功后,將數(shù)據(jù)對(duì)象存在實(shí)例的vaVal屬性下
規(guī)則的優(yōu)先級(jí):
1.自定義規(guī)則 > 選項(xiàng)規(guī)則 > 默認(rèn)規(guī)則
2.規(guī)則中的優(yōu)先級(jí)依照數(shù)組順序
另外,可以看到為了使用者方便,我在我們團(tuán)隊(duì)中事先做了一些約定,并可能會(huì)用到 v-va、v-va-check、tag等指令,占用了實(shí)例的兩個(gè)屬性名vaConfig、vaVal。這些約定和設(shè)置可以使使用者使用方便(通過(guò)配置控制校驗(yàn)時(shí)機(jī), 校驗(yàn)成功后自然生成通過(guò)的數(shù)據(jù)對(duì)象,自定義報(bào)錯(cuò)信息等等)。但是也減少了這個(gè)插件的普適性。
此方案僅提供各位做思路參考。個(gè)人認(rèn)為,表單驗(yàn)證是高度定制化的需求,盡量根據(jù)各個(gè)業(yè)務(wù)情況進(jìn)行取舍。在我的方案中,并不像vue-validator一樣做了臟校驗(yàn)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/81023.html
摘要:今天就來(lái)介紹一下如何利用的自定義指令來(lái)開(kāi)發(fā)一個(gè)表單驗(yàn)證插件的過(guò)程。按照這種方式就能夠使用自己開(kāi)發(fā)的這個(gè)表單校驗(yàn)插件。這段時(shí)間在進(jìn)行一個(gè)新項(xiàng)目的前期搭建,新項(xiàng)目框架采用vue-cli3和typescirpt搭建。因?yàn)轫?xiàng)目比較輕量,所以基本沒(méi)有使用額外的ui組件,有時(shí)候我們需要的一些基礎(chǔ)組件我就直接自己開(kāi)發(fā)了。今天就來(lái)介紹一下如何利用vue的自定義指令directive來(lái)開(kāi)發(fā)一個(gè)表單驗(yàn)證插件的過(guò)...
摘要:寫一個(gè)表單驗(yàn)證插件需求目標(biāo)簡(jiǎn)單易用可擴(kuò)展如何簡(jiǎn)單開(kāi)發(fā)者要做的寫了一個(gè)表單,指定一個(gè),指定其驗(yàn)證規(guī)則。調(diào)用提交表單方法,可以獲取驗(yàn)證成功后的數(shù)據(jù)。 寫一個(gè)vue表單驗(yàn)證插件(vue-validate-easy) 需求 目標(biāo):簡(jiǎn)單易用可擴(kuò)展 如何簡(jiǎn)單 開(kāi)發(fā)者要做的 寫了一個(gè)表單,指定一個(gè)name,指定其驗(yàn)證規(guī)則。 調(diào)用提交表單方法,可以獲取驗(yàn)證成功后的數(shù)據(jù)。 調(diào)用重置表單方法重置表單 自...
摘要:寫一個(gè)表單驗(yàn)證插件需求目標(biāo)簡(jiǎn)單易用可擴(kuò)展如何簡(jiǎn)單開(kāi)發(fā)者要做的寫了一個(gè)表單,指定一個(gè),指定其驗(yàn)證規(guī)則。調(diào)用提交表單方法,可以獲取驗(yàn)證成功后的數(shù)據(jù)。 寫一個(gè)vue表單驗(yàn)證插件(vue-validate-easy) 需求 目標(biāo):簡(jiǎn)單易用可擴(kuò)展 如何簡(jiǎn)單 開(kāi)發(fā)者要做的 寫了一個(gè)表單,指定一個(gè)name,指定其驗(yàn)證規(guī)則。 調(diào)用提交表單方法,可以獲取驗(yàn)證成功后的數(shù)據(jù)。 調(diào)用重置表單方法重置表單 自...
摘要:寫一個(gè)表單驗(yàn)證插件需求目標(biāo)簡(jiǎn)單易用可擴(kuò)展如何簡(jiǎn)單開(kāi)發(fā)者要做的寫了一個(gè)表單,指定一個(gè),指定其驗(yàn)證規(guī)則。調(diào)用提交表單方法,可以獲取驗(yàn)證成功后的數(shù)據(jù)。 寫一個(gè)vue表單驗(yàn)證插件(vue-validate-easy) 需求 目標(biāo):簡(jiǎn)單易用可擴(kuò)展 如何簡(jiǎn)單 開(kāi)發(fā)者要做的 寫了一個(gè)表單,指定一個(gè)name,指定其驗(yàn)證規(guī)則。 調(diào)用提交表單方法,可以獲取驗(yàn)證成功后的數(shù)據(jù)。 調(diào)用重置表單方法重置表單 自...
摘要:示例電話電話錯(cuò)誤信息指示指令對(duì)應(yīng)的表單控件的驗(yàn)證結(jié)果。其主要是根據(jù)驗(yàn)證的結(jié)果進(jìn)行的值的變換。如果為空值則默認(rèn)把所有帶有驗(yàn)證的空間作為需要驗(yàn)證對(duì)象。 cddv vue.js 表單驗(yàn)證插件使用說(shuō)明 版本:1.0.8-6 獲取 github:這里 npm安裝 npm i vue-cdd-validator --save yarn安裝 yarn add vue-cdd-validator 安裝...
閱讀 3205·2023-04-26 03:01
閱讀 3592·2023-04-25 19:54
閱讀 1691·2021-11-24 09:39
閱讀 1447·2021-11-19 09:40
閱讀 4368·2021-10-14 09:43
閱讀 2878·2019-08-30 15:56
閱讀 1545·2019-08-30 13:52
閱讀 1715·2019-08-29 13:05