element UI form表单动态增减表单项
element UI
form表单动态增减表单项
最近接到一个需要自定义表单项的需求,同时需要对新增项进行校验,我们这个项目采用的是element这个UI组件,所以使用的内置的form组件实现功能,但是发现一个坑,折腾了一两个小时,记录一下
下面是官网的例子
<el-form :model="dynamicValidateForm" ref="dynamicValidateForm">
<el-form-item
v-for="(domain, index) in dynamicValidateForm.domains"
:label="'域名' + index"
:key="domain.key"
:prop="'domains.' + index + '.value'"
:rules="{
required: true, message: '域名不能为空', trigger: 'blur'
}"
>
<el-input v-model="domain.value"></el-input>
</el-form-item>
</el-from>
<script>
export default {
data() {
return {
dynamicValidateForm: {
domains: [{
value: ''
}],
email: ''
}
};
},
}
</script>
这里的prop 属性设置是有讲究的,如果你没有按照这个格式设置,下面会一直报找不到匹配值的错误,或者是校验规则一直error,根本无法通过校验。
:prop="'domains.' + index + '.value'"
这里的domains 是表单from绑定值下面循环体的key,index为当前下标,value是当前循环对象v-modal绑定的key。
我们再到element ui 源码中看一下他是如何匹配这个prop
fieldValue() {
const model = this.form.model;
if (!model || !this.prop) { return; }
let path = this.prop;
if (path.indexOf(':') !== -1) {
path = path.replace(/:/, '.');
}
return getPropByPath(model, path, true).v;
}
这里我们发现他是通过getPropByPath 这个方法去获取匹配值,三个参数,第一个就是我们form的绑定值,(即我们示例中的dynamicValidateForm) 第二个就是formItem中绑定的prop (即:prop="'domains.' + index + '.value'")
下面是具体的getPropByPath 匹配方法
export function getPropByPath(obj, path, strict) {
let tempObj = obj;
path = path.replace(/\[(\w+)\]/g, '.$1');
path = path.replace(/^\./, '');
let keyArr = path.split('.');
let i = 0;
for (let len = keyArr.length; i < len - 1; ++i) {
if (!tempObj && !strict) break;
let key = keyArr[i];
if (key in tempObj) {
tempObj = tempObj[key];
} else {
if (strict) {
throw new Error('please transfer a valid prop path to form item!');
}
break;
}
}
return {
o: tempObj,
k: keyArr[i],
v: tempObj ? tempObj[keyArr[i]] : null
};
};
我们看到报错 please transfer a valid prop path to form item! 原因就是prop 没有匹配到数据。prop的规则是根据prop,通过对from的绑定值一层层遍历往下去找,找到了就返回,没找到就会丢出一个error