1、固定表单校验
对于这类校验,iview的文档说的很易懂,在Form上设置属性model(表单数据对象)和rules(表单验证规则),FormIten上设置属性prop(对应表单域 model 里的字段,user)。具体如下:
<template>
<Form ref="formInline" :model="formInline" :rules="ruleInline" inline>
<FormItem prop="user">
<Input type="text" v-model="formInline.user" placeholder="Username">
<Icon type="ios-person-outline" slot="prepend"></Icon>
</Input>
</FormItem>
<FormItem>
<Button type="primary" @click="handleSubmit('formInline')">Signin</Button>
</FormItem>
</Form>
</template>
<script>
export default {
data () {
return {
formInline: {
user: ''
},
ruleInline: {
user: [
{ required: true, message: 'Please fill in the user name', trigger: 'blur' }
]
}
}
},
methods: {
handleSubmit(name) {
this.$refs[name].validate((valid) => {
if (valid) {
this.$Message.success('Success!');
} else {
this.$Message.error('Fail!');
}
})
}
}
}
</script>
1、动态表单校验
对于这类校验,iview的文档不好理解,api的demo看不懂,尤其是**:prop=“‘items.’ + index + ‘.value’”,让人想不通,感觉不合逻辑。我也是试了多次才理解了demo,记录下。
(1)api文档中的说 当需要动态维护 FormItem 时,也可以直接给 FormItem 设置属性 rules 来单独为该域做验证。动态设置 FormItem 的 prop 属性时,会依据上层的 Form 组件的 model 来获取 意思是动态表单的校验要 在FormItem上单独设置rules 和prop ,不是在Form上。
(2)prop如何传?
demo中是这样传的:prop=“‘items.’ + index + ‘.value’”,它的结构是数组变量名 + 遍历索引 + 元素属性名**,它的表单数据结构如下:
formDynamic: {
items: [
{
value: '',
index: 1,
status: 1
}
]
}
正常的要拿到value值应该items[index].value,但是对于动态表单字段value来说应该设置成items.0.value,其中,数组变量名为items, 遍历索引为v-for中的index,元素属性名为value,因此,在考虑要遍历,写成动态的就是**:prop=“‘items.’ + index + ‘.value’”**,这下清楚了吧。
探究原理,找到FormItem源码,路径node_modules/view-design/src/components/form/form-item.vue,在源码中找到答案,
computed:{
fieldValue () {
// FormInstance是当前Form的实例,获取到model,也就questionFormData
const model = this. FormInstance. model;
if (!model|I ! this.prop) { return; }
//此处的prop就是quest ions .0. question
let path = this . prop;
//如果遇到:就替换为点,如questions :0.question -> questions .0.question
if (path. index0f(':') !== -1) {
path = path.replace(/:/, '.');
//获取到questions .0. question在questionFormData的值
return getPropByPath(model, path).v;
function getPropByPath(obj, path) {
// temp0bj = questionFormData
let temp0bj. = obj;
//将中括号替换为.如questions[0][question] -> questions .0. question
path = path.replace(/\[(\w+)\]/g, ' .$1');
//替换首个.questions .0.question -> questions .0.question 最终处理成这个格式
path =. path.replace(/^\./ ,
//分割成数组得到['questions','0', 'question']
let keyArr = path.split('.');
leti=0;
//以i = 0来查此处代码作用
for (1et len = keyArr .length; i < len - 1; ++i) {
// key = questions
let key = keyArr[i];
// questions 在questionFormData中, 进入为true的代码块
if (key in temp0bj) {
// temp0bj = questions
tempobj = temp0bj[key];
} else {
throw new Error('[iView warn]: please transfer a valid prop path to form item!
return {
o: temp0bj, // { id: 1, question: ' 问题1’}
k: keyArr[i], // question
v: temp0bj[keyArr[i]] //问题1
}
}
原来是通过.去分割为数据,数组的值以key的形式去访问model对象,匹配上对应的值。当匹配不上值是会抛出’[iView warn]: please transfer a valid prop path to form item!'错误。
(2)rules如何设置?
第一种,按照demo中的在FormItem上单独设置rules,用于校验简单的情况,如: :rules=“{required: true, message: ‘Item ’ + item.index +’ can not be empty’, trigger: ‘blur’}”
第二种,在data中单独设置,适合于复杂,需自定义规则的情况
如下:
<template>
<FormItem style="width: 200px" :prop="'childrens.' + idx + '.minVal'" :rules="dynamicRules.minonGetIndex(index)" v-model="list.minVal" controls-outside :step="0.1">
</InputNumber>
</FormItem>
</template>
data(){
const validateCheckMax = (rule, value, callback) => {
let field = rule.field || rule.fullField
let index = Number(field.substr(field.indexOf('.') + 1, 1))
if (Number(value) < this.datalist[this.formItemIndex].childrens[index].minVal) {
if (!this.formErrorList.includes(rule.field)) {
this.formErrorList.push(rule.field)
}
callback(new Error('最大值不能小于最小值!'));
} else {
callback();
}
};
const validateCheckMin = (rule, value, callback) => {
let field = rule.field || rule.fullField
let index = Number(field.substr(field.indexOf('.') + 1, 1))
// 单独校验最小值
let temp = 'formDynamic' + this.formItemIndex
this.$refs[temp + index][0].validateField('childrens.' + index + '.minVal')
if (Number(value) > this.datalist[this.formItemIndex].childrens[index].maxVal) {
callback(new Error('最小值不能大于最大值!'));
} else {
callback();
}
};
return{
dynamicRules: {
max: [
{
validator: validateCheckMax
}
],
min: [
{
validator: validateCheckMin
}
]
},
}
}
参考文档
1、https://www.codenong.com/cs107086780/
2、https://www.jb51.net/article/272950.htm