el-tree 懒加载实现远程搜索

3,028 阅读1分钟

需求场景

一棵树的业务数据有几万条,所以用懒加载比较合适。但是要想定位某个叶子节点,就必须要通过后端接口进行过滤数据,并在前端展示过滤后的树结构。而且过滤后的树结构中的叶子节点还可以进行懒加载

实现

思路:el-tree 懒加载第一层级时,根据接口返回的数据,渲染过滤后的树

难点:由于 el-tree 的每次懒加载只能显示一个层级的节点,如果接口返回的数据是多层级的树,那么更深层级的节点就没有渲染出来

解决方案:不用 el-tree 默认的懒加载方式,自己来实现懒加载。查看 el-tree 文档,其中updateKeyChildren方法 和 node-expand事件可以满足需求

image.png image.png

1.el-tree 配置如下

    <el-tree
      ref="tree"
      v-loading="loading"
      node-key="id"
      default-expand-all
      :data="treeData"
      :props="defaultProps"
      :render-content="renderContent"
      @node-expand="nodeExpand"
    />
  1. 使用render-content指定渲染函数
    renderContent(h, { node, data, store }) {
      // 如果是叶子节点,就让展开/收缩按钮显示
      if (node.childNodes.length === 0) {
        node.isLeaf = false
        node.expanded = false
      } else {
        // 如果节点已经展开,并且存在子节点,则loaded设为true
        // 表示已加载过了,下次展开时,就不要请求数据了
        if (node.expanded) node.loaded = true
      }
      return (
        <span class="custom-tree-node">
          <span>{node.label}</span>
        </span>);
    },
  1. node-expand 事件:
    nodeExpand(data, node, vueComponent) {
      // 设置图标为收缩图标,等加载数据后再展开,达到与el-tree默认懒加载同样的效果
      node.expanded = false
      if (!node.loaded) { // 当没有加载过的节点才会请求数据
        node.loading = true
        this.fetchTreeData({type: 'load', id: data.id}).then(res => {
          node.loaded = true
          node.loading = false
          node.expanded = true
          if (res && res.length) {
            // 更新当前节点的子节点
            this.$refs.tree.updateKeyChildren(data.id, res)
          } else {
            node.isLeaf = true
          }
        })
      } else {
        node.expanded = true
      }
    },
  1. 最终效果:

CPT2110301831-606x659.gif