You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ag Grid树形列表过滤器:如何记住展开/折叠状态

树形列表刷新时保留展开/折叠状态的解决方案

不管你用的是Element UI、Ant Design这类现成组件库,还是自己手写的树形列表,核心思路都是先记录当前展开的节点标识,数据刷新后再把这些标识回传给组件,具体实现分几种情况:

1. 用Element UI Tree组件的情况

  • 给Tree组件绑定expanded-keys属性控制展开节点,同时监听node-expand和node-collapse事件,把展开/折叠的节点key同步到变量(比如expandedKeys)里。
  • 刷新数据前先保存当前的expandedKeys,数据加载完成后直接把这个变量赋值给Tree的expanded-keys。
  • 注意:节点的key必须用后端返回的唯一ID这类稳定标识,别用数组索引,不然数据刷新后匹配不上。

示例代码片段:

<el-tree
  :data="treeData"
  :expanded-keys="expandedKeys"
  @node-expand="handleNodeExpand"
  @node-collapse="handleNodeCollapse"
></el-tree>

<script>
export default {
  data() {
    return {
      treeData: [],
      expandedKeys: []
    }
  },
  methods: {
    handleNodeExpand(data) {
      if (!this.expandedKeys.includes(data.id)) {
        this.expandedKeys.push(data.id)
      }
    },
    handleNodeCollapse(data) {
      this.expandedKeys = this.expandedKeys.filter(key => key !== data.id)
    },
    async refreshData() {
      // 保存当前展开状态
      const currentExpanded = [...this.expandedKeys]
      // 加载新数据
      this.treeData = await fetchNewData()
      // 恢复展开状态
      this.expandedKeys = currentExpanded
    }
  }
}
</script>

2. 用Ant Design Tree组件的情况

  • 思路和Element UI类似,通过expandedKeys状态管理展开节点,监听onExpand事件更新这个状态。
  • 数据刷新后,把保存的expandedKeys传给组件即可,同样要保证节点key的唯一性。

示例代码片段:

import { Tree } from 'antd';

const MyTree = () => {
  const [treeData, setTreeData] = useState([]);
  const [expandedKeys, setExpandedKeys] = useState([]);

  const handleExpand = (keys) => {
    setExpandedKeys(keys);
  };

  const refreshData = async () => {
    const currentExpanded = [...expandedKeys];
    const newData = await fetchNewData();
    setTreeData(newData);
    setExpandedKeys(currentExpanded);
  };

  return (
    <Tree
      treeData={treeData}
      expandedKeys={expandedKeys}
      onExpand={handleExpand}
    />
  );
};

3. 自己手写树形列表的情况

  • 给每个节点分配唯一ID,用localStorage或者全局状态管理工具(比如Vuex、Redux)存储展开的节点ID列表。
  • 渲染节点时,根据存储的ID列表判断是否展开;点击展开/折叠时,更新存储的列表。

示例逻辑:

// 存储展开节点到localStorage
const saveExpandedNodes = (keys) => {
  localStorage.setItem('treeExpandedKeys', JSON.stringify(keys));
};

// 获取保存的展开节点
const getExpandedNodes = () => {
  const keys = localStorage.getItem('treeExpandedKeys');
  return keys ? JSON.parse(keys) : [];
};

// 渲染节点时判断展开状态
const renderTreeNode = (node) => {
  const expandedKeys = getExpandedNodes();
  const isExpanded = expandedKeys.includes(node.id);
  
  return (
    <div className="tree-node">
      <div onClick={() => toggleExpand(node.id)}>
        {isExpanded ? '▼' : '▶'} {node.name}
      </div>
      {isExpanded && node.children && node.children.map(child => renderTreeNode(child))}
    </div>
  );
};

// 切换展开状态并更新存储
const toggleExpand = (nodeId) => {
  const expandedKeys = getExpandedNodes();
  const newKeys = expandedKeys.includes(nodeId) 
    ? expandedKeys.filter(key => key !== nodeId) 
    : [...expandedKeys, nodeId];
  saveExpandedNodes(newKeys);
  // 触发重新渲染
};

注意事项

  • 绝对不要用数组索引作为节点唯一标识,数据刷新后索引会变化,导致展开状态匹配错误。
  • 如果过滤后节点有新增或删除,要额外处理:比如删除的节点要从展开列表中移除,新增节点可根据业务需求决定是否自动展开。

内容的提问来源于stack exchange,提问作者khchew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 05:51:33