antd虚拟滚动树图结合筛选实现

背景:

由于树图数量大的时候,会变得卡顿,因此需要开启虚拟滚动。

  1. 虚拟滚动的树图,又必须全量展示数据。
  2. 需要通过筛选,限制了全量展示数据。

因此,这两者存在矛盾,需要通过代码,较为友好的兼容。

注: 之前试过把不需要的进行隐藏,但是最终发现,依旧存在卡顿现象。

步骤:

  1. 树图开启虚拟滚动
ts 复制代码
<Tree virtual>
  1. 节点注入额外数据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);
  1. 过滤筛选值 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

  1. 渲染树图 执行方法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],
);
  1. 判断树图 执行onCheck方法, noIncludeKey: 得到原有树图有的keys,但是现有树图未包含的keys。这些需要一直推进去 relateKeysrelateKeys: 关联的树图,这部分需要后端传参做特殊处理 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,
    ]),
  ]);
};
相关推荐
Boilermaker19921 小时前
【Java EE】SpringIoC
前端·数据库·spring
中微子1 小时前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上10241 小时前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y2 小时前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁2 小时前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry2 小时前
Fetch 笔记
前端·javascript
拾光拾趣录2 小时前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟2 小时前
vue3,你看setup设计详解,也是个人才
前端
Lefan2 小时前
一文了解什么是Dart
前端·flutter·dart
Patrick_Wilson2 小时前
青苔漫染待客迟
前端·设计模式·架构