1.渲染树形控件
树形控件的结构是一层层嵌套的,官网上定义好的结构中属性名我们无法更改,实际开发中后台返回的字段名与属性名也会不一致,这里我们用到了“递归”的方法将结构中的属性赋予实际开发中的值。
(1)树形结构如下:
<el-tree
v-model="form.treeData"
:data="treeData"
show-checkbox
node-key="id"
ref="tree"
@check="handleNodeCheck">
</el-tree>
data() {
return {
treeData: [],
form: { // 表单
treeData: []
},
selectedId: [] // 选中节点id的集合
}
}
// 绑定的data结构(我们以三级结构为例)
treeData: [
id: 0,
label: '一级'
children: [
{
id: 0,
label: ‘二级’,
children: [
{
id: 0,
label: '三级'
}
]
}
],
]
我们这里给这个控件绑定一个ref标识,这样就可以通过这个标识调用方法。接下来发请求获取数据,后台返回的数据也需要经过处理成一层层嵌套的方便操作。
(2)对获取的后端数据进行处理
// 后端返回的结构
data: [
id: 0,
name: 'name1',
list1: [
{
id: 0,
name: 'name2',
list2: [
{
id: 0,
name: 'name3',
code: 1
}
]
}
]
]
// 发请求
this.axios.get(url).then(res => {
if (res.data.success === false) {
this.$message({
type: 'error',
message: res.data.msg
})
} else {
console.log('查询数据', res);
this.dataCount(this.treeData, res.data.data, 0);
}
this.isLoading = false;
}).catch(err => {
console.log('查询数据', err);
})
// 递归函数
dataCount(treeData, data, level) {
let that = this;
data.map((item, index) => {
if (level === 0) {
treeData.push({
id: item.id,
label: item.name,
children: []
})
if (item.list1.length > 0) {
that.dataCount(treeData[index].children, item.list1, 1);
}
} else if (level === 1) {
treeData.push({
id: item.id,
label: item.name,
children: []
})
if (item.list2.length > 0) {
that.dataCount(treeData[index].children, item.list2, 2);
}
} else if (level === 2) {
treeData.push({
id: item.id,
label: item.name,
code: item.code // 如果有其他属性也可以自行添加
})
}
})
},
2.树形控件的方法
// 通过node获取,返回节点信息的集合
this.$refs.tree.getCheckedNodes();
// 通过key获取,返回id的集合
this.$refs.tree.getCheckedKeys();
// 通过node设置回显
this.$refs.tree.setCheckedNodes( [ { id: 0, label: '二级' }, { id: 0, label: '三级' } ] );
// 通过key设置回显
this.$refs.tree.setCheckedKeys([0, 1]);
// 清空选中值
this.$refs.tree.setCheckedKeys([]);
2.数据的回显与重置
前端在表单提交完之后,需要进行再次编辑的表单涉及到数据回显问题,树形结构的回显也可以通过递归方法实现。有时候需求可能要加上禁止勾选的功能,可通过后台返回一个字段有无去设置disabled属性。
// 回显、重置函数
dataEcho(treeData, id, flag, level) {
treeData.map((item, index) => {
if (level === 0) {
this.dataEcho(treeData[index].children, id, flag, 1);
} else if (level === 1) {
this.dataEcho(treeData[index].children, id, flag, 2);
} else if (level === 2) {
if (treeData[index].code === id) { // 后台返回的code和树形结构code匹配
this.selectedId.push(treeData[index].code);
if (flag) { // 判断flag有无设置禁止勾
treeData[index].disabled = true;
}
}
if(id){ // 重置
that.selectedData = [];
treeData[index].disabled = false;
}
}
})
}
// treeData:渲染整个树形结构的数据
// codeArr:后台返回上一次选中的树形结构数据
let that = this;
codeArr.forEach(item => {
that.equipmentEcho(this.treeData, item.code, true, 0);
})
that.addFormVisible = true; // 显示dialog弹框
setTimeout(() => {
that.$refs.tree.setCheckedKeys(this.selectedData); // 将匹配完的id设置回显数据
}, 500)
// 重置调用
that.$refs.tree.setCheckedKeys([]);
that.equipmentEcho(this.treeData, '', '', 0);
3.提交表单验证
表单里面的树形结构在提交验证的时候要给个v-model 属性,和“:data”区分开来,在rules里面的trigger事件要使用“click”。
rules: {
equipment: [
{ required: true, message: '请选择', trigger: 'click' }
]
}
但是加上rules后,这时你每次选中一项都会提醒你请选择,因为v-model绑定的treeData一直为空,我们在选中每一项之后应该给treeData里面赋值,需要监听树结构的check事件。在check事件里面的处理逻辑:
handleNodeCheck() {
this.from.treeData = this.$refs.tree.getCheckedNodes();
}