模拟后端返回数据
通过函数返回promise模拟后端返回的数据,并获取数据。里面的findFirstLevel函数是寻找表格的顶级节点的函数,文章后面会对它做详细介绍。
const getData_imitate = (): Promise<tableItem[]> => {
return new Promise(function (resolve, reject) {
setTimeout(() => {
resolve([
{ id: 1, name: "第一事业部", parentId: 0 },
{ id: 2, name: "第二事业部", parentId: 0 },
{ id: 3, name: "第三事业部", parentId: 0 },
{ id: 4, name: "第一研发部", parentId: 1 },
{ id: 5, name: "第一交付部", parentId: 1 },
{ id: 6, name: "第二研发部", parentId: 2 },
{ id: 7, name: "第二交付部", parentId: 2 },
{ id: 8, name: "第二运维部", parentId: 2 },
{ id: 9, name: "第二运维交付部", parentId: 8 },
{ id: 10, name: "第三研发部", parentId: 3 },
{ id: 11, name: "第三交付部", parentId: 3 },
]);
}, 10);
});
};
const getList = async () => {
list.value = await getData_imitate();
firstLevel = findFirstLevel(list.value);
};
getList();
标签中的内容
其中firstLevel获取顶级节点中的数据内容,lazy代表懒加载,loadData代表展示子节点数据的方法,tree-props可以代表可以设置children和hasChildren字段的具体名称。
<ElTable
:data="firstLevel"
lazy
:load="loadData"
row-key="id"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<ElTableColumn prop="name" label="部门名称" />
</ElTable>
获取扁平数组顶级节点
首先,通过allParentId和allId记录数组中所有的parentId和id;之后我们要想要筛选出所有顶级节点,那什么样的才是顶级的节点呢?--那自然是在这个数组中没有父亲的,也就是说那些parentId不在allId数组中的就是顶级节点了;之后操作还没有结束,我们还要判断对应的顶级节点还有没有孩子节点,同样的问题来了:什么样的节点是有孩子节点的呢?--自然是自己的id存在在allParentId的时候,这时候证明自己是其他节点的父亲,这种情况下设置字段hasChildren为true
const findFirstLevel = (list: tableItem[]) => {
// 记录所有的parentId和id
const allParentId: number[] = [];
const allId: number[] = [];
list.forEach((item) => {
if (!allParentId.includes(item.parentId)) {
allParentId.push(item.parentId);
}
if (!allId.includes(item.id)) {
allId.push(item.id);
}
});
// 先筛选出 父节点在所有数据中不存在的 --无父节点 --顶层节点
firstLevel.value = list.filter((item) => !allId.includes(item.parentId));
// 再判断顶级节点是否有孩子 --hasChildren的值的判断
firstLevel.value.forEach((item) => {
if (item.id in allParentId) {
// 说明存在子节点
item.hasChildren = true;
}
});
return firstLevel;
};
获取孩子的数据
首先介绍一下table的load属性,给这个属性赋值为一个函数loadData,其中row为点击的本行的数据,resolve接受一个数组:这个数组就是点击这个节点的孩子数据的数组。
flagChidren函数可以判断数组中有没有自己的孩子并返回一个加上是否有孩子标识字段的孩子数组:首先还是先获取所有parentId的数组存储为allParentId;之后筛选出是点击这个节点孩子的数组;之后我们还要判断这些孩子节点还有没有孩子,把有孩子的hasChildren字段设置为true,这样就实现了这个树形table的懒加载。
const loadData = (row, treeNode, resolve) => {
resolve(flagChildren(list.value, row));
};
// 写一个函数 --可以判断数组中有没有自己的孩子 --返回一个加上是否有孩子标识字段的孩子数组
const flagChildren = (list, parentItem, config = {}) => {
// list是扁平化数组 parentItem是点击的行的数据对象 config是参数配置
config = Object.assign({}, { id: "id", parentId: "parentId" }, config);
const allParentId: number[] = [];
list.forEach((item) => {
if (!allParentId.includes(item["parentId"])) {
allParentId.push(item["parentId"]);
}
});
// 筛选出是这个节点孩子的 节点的数组
const childrenArr = list.filter((item) => {
return item["parentId"] == parentItem["id"];
});
// 判断他的孩子数组中哪个孩子有haschildren属性
childrenArr.forEach((item) => {
if (allParentId.includes(item["id"])) {
// 证明有孩子节点
item["hasChildren"] = true;
}
});
return childrenArr;
};