el-tree分页懒加载的实现

功能描述:

项目要求el-tree懒加载, 因为树结构中的数据太多, 所以每层节点需要使用分页多次加载,具体的实现效果如下图:
在这里插入图片描述

实现思路:

  1. 懒加载很简单, 参照element-ui文档即可
  2. 根节点的加载更多也简单, 记录初始的node及resolve即可
  3. 其他节点的分页加载逻辑就稍微复杂一点, 需要复写el-tree自带的load方法,load方法内携带两个返回参数,一个是node,一个是resolve,即懒加载数据必须是通过resolve就是return 将数据带回,所以在初次加载的时候就需要记录下当前的node和resolve, 其次就是记录当前节点下数据的总数并再每次点击加载更多的时候对当前节点下的页码进行累加

实现代码

<template>
  <div v-dee-loading="loading" class="demo">
          <el-tree
            ref="treeRef"
            v-dee-loading="list.loading"
            accordion
            node-key="id"
            :load="loadNode"
            lazy
            :props="defaultProps"
            :expand-on-click-node="false"
            @node-click="handleNodeClick"
          >
            <div slot-scope="{ node, data }" class="custom-tree-node">
              <!-- 查看更多 -->
              <span
                v-if="data.id ==='loadmore'"
                class="tree-node loadmore"
                @click="loadMoreNode(node,data)"
              >
                <el-link>{{ node.label }}</el-link>
              </span>
              <!-- 普通节点 -->
              <span v-else class="span-tree-node">
                {{ node.label }}
              </span>
            </div>
          </el-tree>
          <!-- 根节点数据加载更多(分页)-->
          <div class="more-bar">
            <span v-if="curpage[0]* pageSize < total[0]" class="more" @click="loadMoreOut">加载更多</span>
            <span v-else>已全部加载!</span>
          </div>
          </div>
</template>
<script>
export default {
  name: 'Demo',
  components: {},
  props: {},
  data() {
    return {
      loading: false,
      list: {
        loading: false,
        isExpand: false
      },
      defaultProps: {
        label: 'name',
        children: 'children',
        isLeaf: 'leaf'
      },
      curNode: {},
      resolveFunc: [],
      node0: {},
      resolveFunc0: function() {},
      total: {},
      curpage: {},
      pageSize: 100
    }
  },
  created() {},
  mounted() {
  },
  methods: {
    async  loadNode(node, resolve, parentNode = []) {
      const id = node?.data?.id || 0
      //  记录当前节点的当前页码 
      !this.curpage[id] && (this.curpage[id] = 1)
      this.curNode = node
      // 节点各自的resolve
      this.resolveFunc.push({ id: id, resolve: resolve })
      this.resolveFunc = this.resolveFunc.filter((item, index, self) => {
        return self.findIndex(x => x.id === item.id) === index
      })
      if (node.level === 0) {
        this.node0 = node
        this.resolveFunc0 = resolve
        return resolve(await this.getTreeData(null, node.level))
      } else if (node.level >= 1) {
        const data = await this.getTreeData(node.data, node.level)
        // 当前界面的数据小于总数据
        if (this.curpage[id] * this.pageSize < this.total[id]) {
          const nearName = data[data.length - 1].name
          data.push({ name: '查看更多', id: 'loadmore', nearName: nearName,leaf: true, disabled: true })
        }
        // 查看更多加载需根据各自的resolve加载数组数据
        if (parentNode && parentNode.length > 0) {
          parentNode.push(...data)
          return resolve(parentNode)
        } else {
          return resolve(data)
        }
      } else {
        return resolve([]) // 防止该节点没有子节点时一直转圈的问题出现
      }
    },
    getTreeData(nodeData, nodeLevel, node) {
      const curId = nodeData?.id || 0
      this.list.loading = true
      let tags = []
      const params = {xxx:xxx}   //  此处为请求所需参数, 已省略
      return matchingQuery(params).then(res => {
        if (!res.items || !res.items.content) return
        tags = res.items.content || []
        tags.forEach((item, index) => { // 节点需要构建为 tree 的结构
          item.name = `${item.name}-${item.code}`
          item.id = parseInt(Math.random() * 1000000000000, 10)
          item.leaf = false
        })
        this.list.loading = false
        //   存储当前节点下的数据总数
        this.total[curId] = res.items.totalElements   
        return tags
      }).catch(err => {
        console.log('err: ', err)
      }).finally(() => {
        this.list.loading = false
        return tags
      })
    },
    loadMoreNode(node, data) {
      if (data.id === 'loadmore') {
        const nodeParentKey = node.parent.key ? node.parent.key : ' '
        const childNode = {
          data: {
            id: nodeParentKey,
            name: data.nearName,
          },
          level: node.level - 1
        }
        let resolve = ''
        let parentNode = node.parent.childNodes.map(({ key: id, label: name }) => {
          return { name, id }
        })
        // 剔除自定义的“查看更多”项的数据
        if (parentNode.length > 0) {
          parentNode = parentNode.slice(0, -1)
        }
        // 选取resolve返回
        if (parentNode.length <= this.total[nodeParentKey]) {
          resolve = this.resolveFunc.filter((item) => {
            return item.id === nodeParentKey
          })
          //  点击更多时, 当前节点的当前页+1
          this.curpage[nodeParentKey] += 1
          // 调用原生Tree load方法
          this.$refs.treeRef.load(childNode, resolve[0].resolve, parentNode)
        }
      }
    },
    //  根节点加载更多   (为了效果更好一点, 所以根节点的加载方式单独设置样式)
    loadMoreOut(node) {
      if (this.curpage[0] * this.pageSize < this.total[0]) {
        this.curpage[0] += 1
        this.loadNode(this.node0, this.resolveFunc0)
      }
    },
//   此处为重新加载树结构的方法
    reloadTree() {
      this.curpage = {}
      this.node0.childNodes = []
      this.loadNode(this.node0, this.resolveFunc0)
    },
    handleNodeClick(){}
  }
}
</script>
<style  lang="scss">
  .demo{
    height: 100%;
    box-sizing: border-box;
   background-color: #F1F4F5;
   .more-bar {
      margin: 10px auto;
      text-align: center;
      font-size: 12px;
      color: #999;
    }

    .more {
      margin: auto;
      margin-top: 20px;
      color: #2f90e2;
      height: 26px;
      line-height: 26px;
      padding: 0 20px;
      background: rgba(231, 242, 255, 1);
      border-radius: 13px;
      display: inline-block;
      cursor: pointer;
    }
  }
 </style>

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现 el-tree懒加载功能,你可以按照以下步骤进行操作: 1. 配置数据源:首先,你需要配置一个异步数据源,用于提供懒加载的数据。这可以是一个后端接口,返回符合 el-tree 要求的节点数据。 2. 设置懒加载属性:在 el-tree 组件中,设置 `lazy` 属性为 `true`,开启懒加载功能。 3. 实现加载方法:创建一个方法,用于根据节点的信息从数据源中获取子节点数据。可以使用 `load` 属性来指定这个方法。这个方法应该接收一个参数,代表当前节点的数据对象,并返回一个 Promise 对象来异步获取子节点数据。 4. 更新节点数据:在加载方法中,通过调用 `resolve` 方法将获取到的子节点数据传递给它,以更新节点的子节点。 这是一个简单的示例代码,演示了如何实现 el-tree懒加载: ```vue <template> <el-tree :data="treeData" :load="loadTreeData" :lazy="true"></el-tree> </template> <script> export default { data() { return { treeData: [] // 初始化树数据为空 } }, methods: { loadTreeData(node, resolve) { // 调用异步接口获取子节点数据 axios.get('/api/getChildren', { params: { nodeId: node.id } }) .then(response => { const children = response.data.children; // 更新节点的子节点数据 resolve(children); }) .catch(error => { console.error('Failed to load tree data:', error); }); } } } </script> ``` 在上述示例中,`loadTreeData` 方法使用 axios 发起异步请求,根据当前节点的 id 获取子节点数据,并将数据通过 `resolve` 方法传递给 el-tree 组件,以更新节点的子节点。 你可以根据自己的实际情况,调整数据源和加载方法的实现。希望这个示例能帮助你实现 el-tree懒加载功能!如有更多问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值