<el-form
ref="form"
:model="form"
:rules="rules"
style="position: relative; width: 100%"
class="demo-ruleForm"
>
<!-- <span style="color: #f56c6c; position: absolute; z-index: 2; left: 60px; top: 7px">
value必填,并且只能为正整数
</span> -->
<el-table
:data="form.dataSource"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
border
default-expand-all
row-key="uid"
:header-cell-style="{ background: '#E8ECFF', height: '40px', padding: '0' }"
:cell-style="{ height: '40px', padding: '0' }"
>
<!-- label-class-name="is-require" -->
<el-table-column label="name" prop="name" width="400">
<template #default="{ row }">
<el-form-item
:class="errorsUid.includes(row.uid) ? 'is-error' : ''"
:prop="_createFormProp(row, 'name')"
:rules="rules.name"
>
<el-input v-model="row.name" />
</el-form-item>
</template>
</el-table-column>
</el-form>
data(){
const validateName = (rule, value, callback) => {
if (!value) {
return callback(new Error('请输入name'));
}
let fullField = rule.fullField.split('.');
let currentIndex = fullField.splice(0, fullField.length - 1).join('.');
let ruleList = JSON.parse(JSON.stringify(this.form));
let currentObj = eval('ruleList.' + currentIndex);
callback();
};
}
return {
rules: {
name: [
{ required: true, message: '请输入name', trigger: 'blur' },
{ required: true, message: '请输入name', trigger: 'change' },
{ validator: validateName, trigger: 'blur' },
],
},
}
}
methods: {
_createFormProp(row, key) {
let currentRow = this.getIndexByUid(this.form.dataSource, row.uid);
let topIndex = currentRow[0].index;
let childIndexs = '';
if (currentRow.length > 1) {
childIndexs = currentRow.splice(1).reduce((total, cur) => total + '.children[' + cur.index + ']', '');
return 'dataSource[' + topIndex + ']' + childIndexs + '.' + key;
}
return 'dataSource[' + topIndex + '].' + key;
},
getIndexByUid(arr, uid) {
let target = [];
for (let i = 0; i < arr.length; i++) {
let item = arr[i];
let tempObj = {
uid: item.uid,
index: i,
};
if (item.uid == uid) {
target.push(tempObj);
break;
}
if (item.children.length > 0) {
let list = this.getIndexByUid(item.children, uid);
if (list.length > 0) {
target = target.concat(tempObj, list);
}
}
}
return target;
},
}
- prop使用
dataSource[0].children[1].name等形式来嵌套绑定。
- 然后在rules进行验证的时候传递过去的
rule.fullField会完整的包含prop的值,即类似dataSource[0].children[1].name的值。因为该值为字符串直接使用js会当作key值进行解析,因此我们需要将字符串来转换为变量eval,而eval的值不能为this点出来的,需要重新用变量再进行操作。