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,
    ]),
  ]);
};
相关推荐
哟哟耶耶6 分钟前
css-设置元素的溢出行为为可见overflow: visible;
前端·css
sunly_8 分钟前
CSS:跑马灯
前端·css
2301_8187320616 分钟前
用layui表单,前端页面的样式正常显示,但是表格内无数据显示(数据库连接和获取数据无问题)——已经解决
java·前端·javascript·前端框架·layui·intellij idea
yqcoder17 分钟前
npm link 作用
前端·npm·node.js
林涧泣23 分钟前
【Uniapp-Vue3】页面和路由API-navigateTo及页面栈getCurrentPages
前端·vue.js·uni-app
Komorebi゛25 分钟前
【uniapp】获取上传视频的md5,适用于APP和H5
前端·javascript·uni-app
林涧泣30 分钟前
【Uniapp-Vue3】动态设置页面导航条的样式
前端·javascript·uni-app
杰九1 小时前
【全栈】SprintBoot+vue3迷你商城(10)
开发语言·前端·javascript·vue.js·spring boot
Hopebearer_1 小时前
入门 Canvas:Web 绘图的强大工具
前端·javascript·es6·canva可画
m0_748254882 小时前
项目升级Sass版本或升级Element Plus版本遇到的问题
前端·rust·sass