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