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,
    ]),
  ]);
};
相关推荐
dualven_in_csdn1 小时前
搞了两天的win7批处理脚本问题
java·linux·前端
你的人类朋友2 小时前
✍️【Node.js程序员】的数据库【索引优化】指南
前端·javascript·后端
小超爱编程3 小时前
纯前端做图片压缩
开发语言·前端·javascript
应巅3 小时前
echarts 数据大屏(无UI设计 极简洁版)
前端·ui·echarts
Jimmy4 小时前
CSS 实现描边文字效果
前端·css·html
islandzzzz4 小时前
HMTL+CSS+JS-新手小白循序渐进案例入门
前端·javascript·css·html
Senar4 小时前
网页中如何判断用户是否处于闲置状态
前端·javascript
很甜的西瓜4 小时前
typescript软渲染实现类似canvas的2d矢量图形引擎
前端·javascript·typescript·图形渲染·canvas
Allen Bright5 小时前
【CSS-9】深入理解CSS字体图标:原理、优势与最佳实践
前端·css
阿芯爱编程5 小时前
最长和谐子序列,滑动窗口
前端·javascript·面试