背景:
由于树图数量大的时候,会变得卡顿,因此需要开启虚拟滚动。
- 虚拟滚动的树图,又必须全量展示数据。
- 需要通过筛选,限制了全量展示数据。
因此,这两者存在矛盾,需要通过代码,较为友好的兼容。
注: 之前试过把不需要的进行隐藏,但是最终发现,依旧存在卡顿现象。
步骤:
- 树图开启虚拟滚动
ts
<Tree virtual>
- 节点注入额外数据
rootString
,方便后续的判断 对树图的每个节点进行额外的注入,得到treeList
ts
const formatData = (data: TreeItem[], rootString: string[]) => {
for (let i = 0; i < data?.length; i++) {
const node = data[i];
const { title } = node;
const _rootString = cloneDeep(rootString);
_rootString.push(title);
data[i].rootString = _rootString;
dataList.push({ ...node, rootString: _rootString });
if (node.children) {
formatData(node.children, _rootString);
}
}
};
formatData(treeData.tree, []);
setTreeList(treeData.tree);
setShowDataList(dataList);
- 过滤筛选值 3.1. 通过
rootString
,找出符合名字的对应子节点,并在找子节点过程中,通过递归函数findAndPushByKey
把父节点找出,把父节点注入showDataList
3.2 在执行3.1的过程中,需要考虑以下问题
全量数据
markdown
├── 全国
└── 广东
│ ├── 广州
│ └── 深圳
└── 北京
子节点跟父节点均为树节点,如果查询广东
,新拼接的树图,则为
筛选后的树图
markdown
├── 全国
└── 广东
├── 广州
└── 深圳
此时,如果勾选根目录广东
,树图组件会默认将全部key勾选【全国
,广东
,广州
,深圳
】,以至于,取消查询时,由于存在全国
这个key,所以antd展示会是全部树图勾选,也就是勾选项展示为4项,但是树图勾选为5项。
因此,此时需要将查询项往上的父节点,进行特殊标记,方便后面过滤不展示。因此,递归函数findAndPushByKey
加入判断
ts
if (!item.key.includes('temp-') && include === false) {
// 临时拼进去的节点
item.key = `temp-${item.key}`;
}
return item;
3.3 得到树图打平后的结构showDataList
- 渲染树图 执行方法
renderTreeNodes
通过treeList
然后过滤出showDataList
里面需要渲染的树图
ts
const renderTreeNodes = useCallback(
(data: TreeItem[]) => {
const nodeArr = data?.map((item: TreeItem) => {
valueMapKey[item.value] = item.key;
if (item?.children) {
return (
<TreeNode
style={{ height: '100%', display: '' }}
title={
<>
<Tag color="volcano">{item?.pathName}</Tag>
{item?.title}
</>
}
key={item?.key}
// @ts-ignore
powerUserIds={item?.properties?.powerUserIds?.split(',') || []}
>
{renderTreeNodes(item?.children)}
</TreeNode>
);
}
return (
<TreeNode
title={
<>
<Tag color="volcano">{item?.pathName}</Tag>
{item?.title}
</>
}
key={item?.key}
// @ts-ignore
powerUserIds={item?.properties?.powerUserIds?.split(',') || []}
/>
);
});
return nodeArr;
},
[valueMapKey],
);
- 判断树图 执行
onCheck
方法,noIncludeKey
: 得到原有树图有的keys,但是现有树图未包含的keys。这些需要一直推进去relateKeys
,relateKeys
: 关联的树图,这部分需要后端传参做特殊处理keys
: 这里跟3.2 联动,找到temp-
开头的则不注入
js
const onCheck = (
keys: string[],
info: { checked: boolean; node: { powerUserIds: string[] } },
) => {
// 未包含在勾选里面的keys值,持续放进去
const noIncludeKey = checkedKeysValue.filter(
(keys) => showDataList.findIndex((data) => data.key === keys) === -1,
);
/** 匹配的关联keys */
const relateKeys = info.checked
? info.node.powerUserIds.map((item: string) => valueMapKey[item])
: [];
const relateAccount = info.checked ? getRelateAccount(getTreeData, relateKeys) : [];
setCheckedKeysValue([
...new Set([
...noIncludeKey,
...keys.filter((item) => !item.includes('temp-')),
...relateKeys,
...relateAccount,
]),
]);
};