1,util 的getPropByPath方法
//obj:el-form的rules path:el-form-item的props
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;
//将prop的对象取值方式[]的取值改写为.的形式如(target.targetObj的rule,
//遍历rules里的层次结构 {target: { targetObj:xxx }}找到对应的那一集规则
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
};
};
el-form得益于上面的方法,在v-model绑定成数组时,验证时候会从model取当前form-item的prop如 parent.1.age作为path,然后在对应事件触发时,通过fieldValue方法取出准确的值。
这样就做到了,绑定数组型的model 在字段相同时,错误消息都是相对于单个的form-item,否则可能直接找不到
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;
},
form-item递归寻找第一个祖先el-form元素,读取里面的元素
form() {
let parent = this.$parent;
let parentName = parent.$options.componentName;
while (parentName !== 'ElForm') {
if (parentName === 'ElFormItem') {
this.isNested = true;
}
parent = parent.$parent;
parentName = parent.$options.componentName;
}
return parent;
},