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,
    ]),
  ]);
};
相关推荐
开发者小天1 小时前
调整为 dart-sass 支持的语法,将深度选择器/deep/调整为::v-deep
开发语言·前端·javascript·vue.js·uni-app·sass·1024程序员节
李少兄3 小时前
HTML 表单控件
前端·microsoft·html
学习笔记1014 小时前
第十五章认识Ajax(六)
前端·javascript·ajax
消失的旧时光-19434 小时前
Flutter 异步编程:Future 与 Stream 深度解析
android·前端·flutter
曹牧5 小时前
C# 中的 DateTime.Now.ToString() 方法支持多种预定义的格式字符
前端·c#
勿在浮沙筑高台5 小时前
海龟交易系统R
前端·人工智能·r语言
歪歪1005 小时前
C#如何在数据可视化工具中进行数据筛选?
开发语言·前端·信息可视化·前端框架·c#·visual studio
Captaincc6 小时前
AI 能帮你写代码,但把代码变成软件,还是得靠人
前端·后端·程序员
吃饺子不吃馅7 小时前
如何设计一个 Canvas 事件系统?
前端·canvas·图形学
Baklib梅梅7 小时前
无头内容管理系统:打造灵活高效的多渠道内容架构
前端·ruby on rails·前端框架·ruby