上篇講的是async-validator
的基本要素,那麼,如何使用到Element中以及怎樣優雅地使用,就在本篇。html
上篇講到async-validator
由3大部分組成數組
Options
Validate
Rules
基本驗證流程以下dom
const validator = new Validator(rules)
validator.validate(source, callback)
上面中的validator.validate
對應Element中的this.$refs[refName].validate
,只不過被改裝過的。並且在Element中定義<el-form :model='form'>
的:model='form'
,那個form
就是source
。source
的字段名,如source.name
就是form.name
,那麼只要在<el-form-item prop='name'>
設置和source
同樣的字段名name
,就能夠匹配<el-form :rules='rules'>
中的rules.name
。async
很重要的一點,rules.字段名
要和source.字段名
要同樣纔會驗證。函數
<template> <el-form :model='form' ref='domForm' :rules='rules'> <el-form-item prop='name' lable='名字'> <el-input v-model='form.name'> </el-form-item> </el-form> </template>
export default { data() { this.rules = { name: { type: 'string', required: true, trigger: 'blur' } } return { form: { name: '' } } }, methods: { submit() { this.$refs.domForm.validate(valid => { if (!valid) { // 驗證不經過 } // 驗證經過後的處理... }) } } }
上面中validate(callback)
函數已經添加到form元素DOM節點上的屬性中。而後上面還有一個很差的一點。那就是規則的定義方式不夠靈活。ui
好比我有兩個字段firstName
和lastName
。firstName
是必填的,而lastName
是非必填的;且firstName
長度要求大於1小於4而lastName
要求大於1小於6。那麼就要寫兩個不一樣的規則,如今只是2個字段而已,沒什麼,若是有不少個不一樣要求的字段,那要寫不少個不一樣的規則,也要寫不少個規則?豈不是很煩?能不能複用?this
Rules三種定義方式url
{ name(rule, value, callback, source, options) {} }
{ name: { type: 'string', required: true } }
{ name: [{ type: 'string' }, { required: true }] }
函數的方式很強大,若是須要用到options
能夠函數的方式,最經常使用的是對象和數組的方式。如今推薦幾種複用的方法。code
// 返回一個規則數組,必填且字符串長度在2~10之間 export const name = (msg, min = 2, max = 10, required = true) => ([ { required, message: msg, trigger: 'blur' }, { min, max, message: `長度在${min}~${max}個字符`, trigger: 'blur' } ]) // 郵箱 export const email = (required = true) => ([ { required, message: '請輸入郵箱', trigger: 'blur' }, { type: 'email', message: '郵箱格式不對', trigger: 'blur' } ]) /* 自定義驗證規則 */ // 大於等於某個整數 const biggerAndNum = num => (rule, v, cb) => { const isInt = /^[0-9]+$/.test(v) if (!isInt) { return cb(new Error('要求爲正整數')) } if (v < num) { return cb(new Error(`要求大於等於${num}`)) } return cb() } export const biggerInt = (int, required = true) => ([ { required, message: '必填', trigger: 'blur' }, { validator: biggerAndNum(int), trigger: 'blur' } ])
export default class CreateRules { constructor() { super() this.rules = [] } need(msg = '必填', trigger = 'blur') { this.rules.push({ required: true, message: msg, trigger }) return this } url(message = '不是合法的連接', trigger = 'blur') { this.rules.push({ type: 'url', trigger, message }) return this } get() { const res = this.rules this.rules = [] return res } } const createRules = new CreateRules() //規則 const needUrl = createRules.need().url().get() const isUrl = createRules.url().get() // imgUrl必填且是連接;href可選不填,若是填寫必須是連接 const rules = { imgUrl: needUrl, href: isUrl } // deep rule 定義 // urls是數組,長度大於1 // urls的元素是連接 const urls = ['http://www.baidu.com', 'http://www.baidu.com'] const rules = { urls: { type: 'array', min: 1, defaultField: isUrl } }