0
点赞
收藏
分享

微信扫一扫

VUE+ Element UI table 懒加载数据 load 问题

做个橙梦 2022-01-12 阅读 87

VUE + Element UI 树形 table 懒加载问题

这两天项目用到了 element ui 的树形结构做菜单,使用了懒加载机制,导致新增和删除菜单时无法正确加载菜单问题,网上文章找了一大圈,全是同样解决方法,记录一下投机取巧的解决方案:

​ 直接上代码:

<template>
        <el-table:data="dataList"
                  row-key="id"
                  lazy
                  :load="load"
                  node-key="id"
                  ref="tree"
                  :expand-on-click-node="true"
                  :tree-props="{children:'children', hasChildren:'hasChildren'}"
        >

            <!--  列表主体 -->

            <el-table-column>
                <template slot-scope="scope">
                    <el-button @click="createChildren(scope.row,true)">添加下级
                    </el-button>
                    <el-button @click="deleteVerify(scope.row.id)">删除
                    </el-button>
                </template>
            </el-table-column>

        </el-table>
</template>


<script>
    export default {
        data() {
            return {
              createChild: '',
              treeNodeMap: new Map()
            }
        },
        methods: {
          // 删除
          deleteHandle (id) {
              this.deleteHandle(id).then(({ data: res }) => {
                // 刷新父级节点
                this.refreshNode(this.deletePid)
              }).catch(() => {})
          },
          // 添加下级
          createChildren(row, unDown) {
                // 这里只是保存一下当前行
                this.createChild = row
            },
          createChildrenHandle: function (){
            // 如果当前菜单不存在下级菜单则添加
            // 这个是添加下级菜单时,如果当前菜单不存在下级菜单,需要将右边小三角加载出来,这个hasChildren 控制当前菜单是否存在下级菜单
            // 不过这样加载其实也有一个问题,就是在刷新节点的时候,如果当前菜单没有点击 load 进行加载,则 treeNodeMap 中就没有缓存到节点信息(这个暂时不知道怎么解决),导致刷新节点无法获取到数据,
            // 增加第一个子节点的时候无法自动展开
            if (this.createChild.hasChildren !== true){
              this.createChild.hasChildren = true
              // 添加下级菜单并展开当前级别
              this.refreshNode(this.createChild.id)
            }
          },
          // 刷新节点
          refreshNode:function (key) {
            // 刷新节点是根据 id 获取节点数据,然后手动触发 load 事件
            const node = this.treeNodeMap.get(key)
            if (node === undefined){
              return
            }
            // 获取需要刷新节点
            const { row, treeNode, resolve } = node
            // 重新展开节点
            this.load(row, treeNode, resolve);
          },
            load(row, treeNode, resolve) {
              // 缓存当前 Node   **重要
              this.treeNodeMap.set(row.id,{row,treeNode,resolve})
                let myChild = [];

                this.getChildren(id).then(({data: res}) => {
                    if (res.code == 0) {
                        myChild = res.data
                      // 当删除本级菜单下最后一个子菜单后,会遇到不会重新刷新菜单问题
                      // 这个 resolve 实现时判断myChild.length 是否有值,如果有值就会重新给父级菜单赋值并刷新页面,如果 myChild.length == 0 则不会刷新
                      // 这个地方只是投机取巧了
                      if (res.data.length === 0){
                        myChild.length = 1
                      }
                    }
                    resolve(myChild);
                }).catch(() => {
                });
            },
        }
    }
</script>

效果:

初始
添加下级:
添加下级
展开:

展开
删除唯一子节点:
删除唯一子节点
需要注意的地方就是添加第一个,或者删除最后一个子节点时,需要处理一下父级菜单状态。

load(row, treeNode, resolve) 中 resolve 实现:

    loadData: function loadData(row, key, treeNode) {
      var _this = this;

      var load = this.table.load;
      var _states6 = this.states,
          lazyTreeNodeMap = _states6.lazyTreeNodeMap,
          treeData = _states6.treeData;

      if (load && !treeData[key].loaded) {
        treeData[key].loading = true;
        load(row, treeNode, function (data) {
          if (!Array.isArray(data)) {
            throw new Error('[ElTable] data must be an array');
          }
          treeData[key].loading = false;
          treeData[key].loaded = true;
          treeData[key].expanded = true;
          // 这里是判断当前节点是否重新加载子节点判断方式,
          // 上边取巧给 data.length 赋了值,这个地方就能进入判断了, 注意,只是给 data.length = '1' 并不是真正的给 data 赋值
          // 然后就会自动加载空数据
          if (data.length) {
            _this.$set(lazyTreeNodeMap, key, data);
          }
          _this.table.$emit('expand-change', row, true);
        });
      }
    }

最后还是希望杜绝网络文章一大抄,哪怕自己写的不好也要自己多想多写!!

举报

相关推荐

0 条评论