element-ui 树形表格 开启懒加载时默认展开至最后一次展开的地方

45 阅读1分钟

最终效果

事例.gif

完整代码

<template>
  <div style="height: 100%;">
    <el-table ref="lazyTable" :data="tableData" height="100%" style="width: 100%" row-key="id" border lazy :load="load" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
      <el-table-column prop="name" label="姓名">
      </el-table-column>

      <el-table-column prop="date" label="日期">
      </el-table-column>

      <el-table-column prop="address" label="地址">
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      expandRowKeysSet: new Set(['0', '16', '24']), // 自动展开的节点id
      id: 15,
      tableData: [
        { id: '0', name: '节点0', hasChildren: true },
        { id: '1', name: '节点1', hasChildren: true },
        { id: '2', name: '节点2', hasChildren: true },
        { id: '3', name: '节点3', hasChildren: true },
        { id: '4', name: '节点4', hasChildren: true },
        { id: '5', name: '节点5', hasChildren: true },
        { id: '6', name: '节点6', hasChildren: true },
        { id: '7', name: '节点7', hasChildren: true },
        { id: '8', name: '节点8', hasChildren: true },
        { id: '9', name: '节点9', hasChildren: true },
        { id: '10', name: '节点10', hasChildren: true },
        { id: '11', name: '节点11', hasChildren: true },
        { id: '12', name: '节点12', hasChildren: true },
        { id: '13', name: '节点13', hasChildren: true },
        { id: '14', name: '节点14', hasChildren: true },
        { id: '15', name: '节点15', hasChildren: true },
      ],
    }
  },
  async mounted() {
    await this.$nextTick()
    this.expandRowKeysSet.delete('0')
    this.$refs.lazyTable.store.loadData(this.tableData['0'], '0', {})
    window['lazyTableRef'] = this.$refs.lazyTable.store
  },
  methods: {
    generatorTableData() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          const childData = [
            { id: `${this.id + 1}`, name: `节点${this.id + 1}`, hasChildren: true },
            { id: `${this.id + 2}`, name: `节点${this.id + 2}`, hasChildren: true },
            { id: `${this.id + 3}`, name: `节点${this.id + 3}`, hasChildren: true },
            { id: `${this.id + 4}`, name: `节点${this.id + 4}`, hasChildren: true },
            { id: `${this.id + 5}`, name: `节点${this.id + 5}`, hasChildren: true },
          ]
          resolve(childData)
          this.id += 5
        }, 400);
      })
    },
    async load(tree, treeNode, resolve) {
      const res = await this.generatorTableData()
      resolve(res)
      await this.$nextTick()
      if (this.expandRowKeysSet.size) {
        for (let i = 0; i < res.length; i++) {
          if (this.expandRowKeysSet.has(res[i].id)) {
            this.$refs.lazyTable.store.loadData(res[i], res[i].id, {})
            this.expandRowKeysSet.delete(res[i].id)
          }
        }
      }
    }
  }
}
</script>

调用el-table自身的 loadData 去调用 load 方法

Snipaste_2025-09-17_16-53-48.png

过程遇到的问题

开始id使用的为数字,会导致id 为 0 的数据展开后不能收起

Snipaste_2025-09-17_17-09-19.png

根据id查找层级路径

/**
 * 根据 id 查找 id 的层级路径
 * @param { string } id target
 * @returns { Array<string> } idPath
 */
export function getPathById(id) {
  const { treeData, _data: data } = this.$refs.lazyTable.store.states.treeData

  // 递归查找
  const handler = (key, path) => {
    const children = treeData[key].children
    if (children && children.length) {
      for (let j = 0; j < children.length; j++) {
        if (children[j] === id) {
          return path
        } else {
          path.push(children[j])
          const resPath = handler(children[j], path)
          if (resPath) return resPath
          path.pop()
        }
      }
    }
  }

  // 从根节点节点开始查找
  for (let i = 0; i < data.length; i++) {
    const key = data[i].id
    if (key === id) return []
    const path = [key]
    const resPath = handler(key, path)
    if (resPath) return resPath
  }

  return undefined
}