实现思路
- 1、设置 Table 的
lazy
属性为 true 与加载函数load
。通过指定 row 中的hasChildren
字段来指定哪些行是包含子节点。children
与hasChildren
都可以通过tree-props
配置。 - 2、将
hasChildren
始终设置为true,当返回数据为空时,箭头消失,显示.el-table__placeholder控制的小圆点。 - 3、mounted中调用getList()获取一级数据
- 4、点击箭头时,调用loadFrame加载函数,获取当前节点的子级数据,通过resolve(data)渲染到页面上。同时,将loadFrame方法中点击加载子节点时信息保存到mapData中。
- 5、添加、编辑、删除成功后,调用updatePage()。mapData中保存着点击过的节点信息,而局部更新页面就是通过找到当前节点的父级,调用loadFrame()来实现的。
代码
html
<el-table :data="tableData" row-key="id" lazy :load="loadFrame" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" :default-expand-all="false" class="frameTable">
<!--表格内容-->
</el-table>
css
<style scoped lang="scss">
.frameTable {
.el-table__placeholder {
display: inline-block;
width: 7px;
height: 7px;
border-radius: 50px;
background: #cbd0db;
margin: 8px 8px 0;
}
}
</style>
js
//data中定义
mapData:new Map()
// 表格列表数据(一级)
getList() {
showSubjectList(this.doseach()).then(res => {
if (res.status == 1) {
res.value.subjectList.forEach(item => {
item.hasChildren = true;
});
this.tableData = res.value.subjectList;
}
});
},
// 加载(子级数据)
loadFrame(tree, treeNode, resolve) {
this.mapData = this.mapData.set(tree.id, { tree, treeNode, resolve });
selectChildrenSubjectByParentId({ parentId: tree.id }).then(res => {
if (res.status == 1) {
res.value.forEach(item => {
item.hasChildren = true;
});
resolve(res.value);
}
});
},
//更新页面(添加编辑删除后调用该方法,val为当前行的数据)
updatePage(type, val) {
let id = 0;
if (type == 'edit' || type == 'open') {//编辑/删除
id = val.parentId;
if (this.mapData.has(id)) {// 点击过
const { tree, treeNode, resolve } = this.mapData.get(id);
this.loadFrame(tree, treeNode, resolve);
} else {// 未点击
this.getList();
}
} else if (type == 'add') {//添加一级数据
this.getList();
} else if (type == 'addSon') {//添加子级
id = val.id;
if (this.mapData.has(id)) {// 点击过
const { tree, treeNode, resolve } = this.mapData.get(id);
this.loadFrame(tree, treeNode, resolve);
}
}
},