web技术分享| 虚拟 tree
Posted anyRTC
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了web技术分享| 虚拟 tree相关的知识,希望对你有一定的参考价值。
查了好久,觉得使用 Ant Design Vue 中的 Tree 树形控件
因项目需求,节点的移动不通过拖拽移动,需要通过弹窗实现节点的移动,因此基于添加、删除实现。
当前仅使用节点添加、删除、移动(删除+添加)以及懒加载。
开发中移动时注意懒加载的值,否则移动后,已经展开的节点无法正常展开
使用 Tree
tree 引入
使用 Ant Design Vue 中的 Tree 树形控件 引入 Tree
- 具体引入方式查看 Ant Design Vue 文档
组件使用
template
-
expandedKeys 展开指定的树节点
-
loadedKeys 已经加载的节点,需要配合 loadData 使用(控制是否进行懒加载,移动(删除+添加)所需):保存 key 表示该节点已进行懒加载(如果删除该节点将会重新懒加载)
-
height 固定高度,虚拟滚动
相关代码:
<a-tree
v-model:expandedKeys="MonitorArea.expandedKeys"
v-model:loadedKeys="MonitorArea.loadedKeys"
:height="510"
:tree-data="MonitorArea.options"
:load-data="onLoadData"
>
<-- 展开折叠自定义 -->、
<template #switcherIcon=" expanded ">
<img
v-if="expanded"
class="w-5 h-5"
src="@/assets/img/spread.png"
draggable="false"
alt=""
/>
<img
v-else
class="w-5 h-5"
src="@/assets/img/fewer.png"
draggable="false"
alt=""
/>
</template>
<template #title="item">
...内容自定义...
</template>
</a-tree>
ts 相关方法
在 vue3 setup 中
- 在懒加载中保存已经加载的节点
const MonitorArea = reactive(
// 默认展开指定节点
expandedKeys: [""],
loadedKeys: [""],
// 内容
options: [] as any[],
// 字段替换
fieldNames:
children: "children",
title: "name",
key: "deviceId",
,
;
/** 懒加载 **/
const onLoadData: TreeProps["loadData"] = (treeNode) =>
return new Promise(async (resolve) =>
// 是否是子叶点(无 childern)
if (treeNode.dataRef?.isLeaf)
resolve();
return;
// 保存 key 表示该节点已进行懒加载(如果删除该节点将会重新懒加载)
MonitorArea.loadedKeys.push(对应节点的key);
treeNode.dataRef!.children = 对应节点的子节点列表
MonitorArea.options = [...MonitorArea.options];
resolve();
/** 创建子节点 **/
searchOption(
Object.assign(子节点信息,
isLeaf: true,
),
MonitorArea.options,
"add"
);
/** 删除子节点 **/
searchOption(子节点信息, MonitorArea.options);
/** 移动(删除+添加)节点 **/
// 删除老数据
await searchOption(老数据, MonitorArea.options);
// 过滤掉旧的节点以及父节点相关懒加载
MonitorArea.loadedKeys = MonitorArea.loadedKeys.filter((item) =>
return 过滤;
);
// 同上
MonitorArea.expandedKeys = MonitorArea.expandedKeys.filter((item) =>
return 过滤;
);
// 添加移动后的数据
searchOption(
Object.assign(移动后的数据,
isLeaf: 判断是否存在childern,
),
MonitorArea.options,
"add"
);
封装 递归查询
const searchOption = (
option: deviceId: string; parentId: string; name: string ,
arr: any[],
type = "delect"
) =>
for (let s = 0; s < arr.length; s++)
// console.log(type, option.deviceId, arr[s].deviceId);
if (type === "edit" && arr[s].deviceId === option.deviceId)
// 编辑
arr[s].name = option.name;
break;
else if (type !== "edit" && arr[s].deviceId === option.parentId)
// 父节点-添加
if (type === "add")
if (!arr[s].children)
arr[s].children = [];
const isExist = arr[s].children.some((item: deviceId: string ) =>
return item.deviceId === option.deviceId;
);
if (!isExist)
arr[s].childIsNull = 0;
arr[s].isLeaf = false;
arr[s].class = "show_line";
arr[s].children.unshift(option);
// 父节点-删除
if (type === "delect")
arr[s].children = arr[s].children.filter(
(item: deviceId: string ) =>
return item.deviceId !== option.deviceId;
);
if (arr[s].children.length == 0)
arr[s].isLeaf = true;
arr[s].class = "";
arr[s].childIsNull = 1;
break;
else if (arr[s].children && arr[s].children.length > 0)
// 递归条件
searchOption(option, arr[s].children, type);
else
continue;
;
以上是关于web技术分享| 虚拟 tree的主要内容,如果未能解决你的问题,请参考以下文章