element UI表单默认使用async-validator做验证,对它的用法做一些介绍。
一、基本用法
1 <template> 2 <el-form ref="ruleForm" :model="ruleForm" :rules="rules"> 3 <el-form-item label="名称" prop="name"> 4 <el-input v-model="ruleForm.name" autocomplete="off"></el-input> 5 </el-form-item> 6 <el-form-item label="年龄" prop="age"> 7 <el-input v-model.number="ruleForm.age"></el-input> 8 </el-form-item> 9 <el-form-item> 10 <el-button type="primary" @click="onSubmit">确定</el-button> 11 </el-form-item> 12 </el-form> 13 </template> 14 15 <script> 16 export default { 17 data() { 18 return { 19 ruleForm: { 20 name: "", 21 password: "", 22 age: "", 23 }, 24 rules: { 25 name: [{ required: true, trigger: "blur" }], 26 age: [{ required: true, trigger: "blur", message: "年龄不能为空" }], 27 }, 28 }; 29 }, 30 methods: { 31 onSubmit() { 32 this.$refs.ruleForm.validate((valid) => { 33 console.info(valid); 34 }); 35 }, 36 }, 37 }; 38 </script>
1.创建form表单,绑定model及校验规则rules,给表单项绑定prop属性,需要注意prop、v-model、rules三者一致
1 <el-form-item label="年龄" prop="age"> 2 <el-input v-model.number="ruleForm.age"></el-input> 3 </el-form-item>
如prop的age、文本域的v-model: age,rules.age。
2.添加校验规则
1 rules: { 2 name: [{ required: true, trigger: "blur" }], 3 age: [ 4 { required: true, trigger: "blur", message: "年龄不能为空" }, 5 { min: 18, max: 29, type: "number", trigger: ['blur', 'change'] , message: "年龄必须在18-29之间"} 6 ], 7 }
required为必填校验,
trigger为校验的触发时机,有blur和change,或trigger: ['blur', 'change']
message为校验不通过时的提示消息
校验规则可以添加多条。
二、规则说明
required必填
type类型,可选值有string、number、boolean、methdod、regexp、integer、float、array、object、enum、date、url、email
pattern,需要符合的正则,如
1 { pattern: /^([a-zA-Z])\w*/g, message: '不符合标识符规则', trigger: 'blur' },
range,需要添加min和max属性,如果是字符串和数组,则要求其长度满足min和max之间,如果是数字则需要满足其值在min和max之间
length,需要添加len属性,如果是字符串和数组,则要求其长度等于len,如果是数字则需要满足其值等于len
enumberable,通过enum指定可使用的枚举值
三、自定义校验规则
如不允许输入的属性和已有的重复时,async-validator自有的规则就不能满足了,需要自定义校验规则。
自定义规则使用validator接收一个函数,
1 { validator: this.repeatValidate, message: '属性不能重复', trigger: 'blur' },
repeatValidate函数有三个参数,rule为校验规则,value为输入的值,callback为校验的回调,
repeatValidate (rule, value, callback) { ... callback() }
完整代码如下:
1 <template> 2 <el-form ref="ruleForm" :model="ruleForm" :rules="rules"> 3 <el-form-item label="名称" prop="name"> 4 <el-input v-model="ruleForm.name" autocomplete="off"></el-input> 5 </el-form-item> 6 <el-form-item label="年龄" prop="age"> 7 <el-input v-model.number="ruleForm.age"></el-input> 8 </el-form-item> 9 <el-form-item label="新的属性" prop="newProperty"> 10 <el-input v-model.number="ruleForm.newProperty"></el-input> 11 </el-form-item> 12 <el-form-item> 13 <el-button type="primary" @click="onSubmit">确定</el-button> 14 </el-form-item> 15 </el-form> 16 </template> 17 18 <script> 19 export default { 20 data() { 21 return { 22 propperties: ["a", "b", "c", "d"], 23 ruleForm: { 24 name: "", 25 password: "", 26 age: "", 27 newProperty: "", 28 }, 29 rules: { 30 name: [{ required: true, trigger: "blur" }], 31 age: [ 32 { required: true, trigger: "blur", message: "年龄不能为空" }, 33 { 34 min: 18, 35 max: 29, 36 type: "number", 37 trigger: ["blur", "change"], 38 message: "年龄必须在18-29之间", 39 }, 40 ], 41 newProperty: [ 42 { required: true, message: '名称不能为空', trigger: 'blur' }, 43 { pattern: /^([a-zA-Z])\w*/g, message: '不符合标识符规则', trigger: 'blur' }, 44 { validator: this.repeatValidate, message: '属性不能重复', trigger: 'blur' } 45 ], 46 }, 47 }; 48 }, 49 methods: { 50 onSubmit() { 51 this.$refs.ruleForm.validate((valid) => { 52 console.info(valid); 53 }); 54 }, 55 repeatValidate (rule, value, callback) { 56 let match = this.propperties.find(item => item === value) 57 if (match) { 58 callback(new Error('重复了')) 59 } 60 callback() 61 } 62 }, 63 }; 64 </script>
四、常见问题
1.属性名中含有"."的处理
如有个属性的名称中含有“.”,
1 <el-form-item label="价格" :prop="'book.price'"> 2 <el-input v-model.number="ruleForm['book.price']"></el-input> 3 </el-form-item>
1 ruleForm: { 2 "book.price": "", 3 name: "", 4 password: "", 5 age: "", 6 newProperty: "", 7 }
Error in mounted hook: "Error: please transfer a valid prop path to form item!"
原因在于prop认为对应的属性为:ruleForm.book.price,也就是
1 ruleForm: { 2 book: { 3 price: "", 4 } 5 }
而不是ruleForm['book.price']。所以不建议使用带“.”的字段名。
2.动态表单校验
表单项是动态生成的一系列表单,不能预先为每一个表单项设置prop属性,这样可以利用特殊的索引设置prop。
如生成表单项的数据为books列表,这样设置 :prop="'books.' + index + '.name'",同时把规则绑定在表单项上。
完整代码如下:
1 <template> 2 <div> 3 <el-button type="primary" @click="addBook">添加书籍</el-button> 4 <el-form ref="ruleForm" :model="ruleForm"> 5 <el-form-item 6 label="书名" 7 :key="item.key" 8 :prop="'books.' + index + '.name'" 9 :rules="dynamic" 10 v-for="(item, index) in ruleForm.books" 11 > 12 <el-input v-model="item.name"></el-input> 13 </el-form-item> 14 <el-form-item> 15 <el-button type="primary" @click="onSubmit">确定</el-button> 16 </el-form-item> 17 </el-form> 18 </div> 19 </template> 20 21 <script> 22 export default { 23 data() { 24 return { 25 ruleForm: { 26 books: [], 27 }, 28 dynamic: [{ required: true, message: "名称不能为空", trigger: "blur" }], 29 }; 30 }, 31 methods: { 32 addBook() { 33 this.ruleForm.books.push({ 34 name: "", 35 key: Date.now(), 36 }); 37 }, 38 onSubmit() { 39 this.$refs.ruleForm.validate((valid) => { 40 console.info(valid); 41 }); 42 }, 43 }, 44 }; 45 </script>
3.下拉框失焦时不触发校验
对于select,失焦时常常不能触发校验,如下没有选择内容失焦时不能触发必填校验。
可以给select添加blur和change的处理函数,在处理函数中调用表单的validateField方法,单独对该字段进行校验。
建议同时添加blur和change的处理函数,不然会出现blur时校验,但选择内容后校验不消失的问题。
1 <el-form-item 2 label="选择" 3 prop="selProp" 4 :rules="{ 5 required: true, 6 message: 'select不能为空', 7 trigger: ['blur', 'change'], 8 }" 9 > 10 <el-select v-model="ruleForm.selProp" @blur="blurHandler('selProp')" @change="blurHandler('selProp')"> 11 <el-option value="1">A</el-option> 12 <el-option value="2">B</el-option> 13 </el-select>
1 blurHandler(prop) { 2 this.$refs.ruleForm.validateField(prop, (val) => { 3 console.info(val); 4 }); 5 },