实现El-table的表格的一键展开所有项,在懒加载的情况下

背景

1、本来table表自带一个默认全部展开,但是是初次渲染的时候,需求是增加一个按钮实现一键展开和关闭的切换。
2、其实简单的一键展开实现还好,但需求有增加了难度,表格是懒加载的,那意思就是,需要先获取所有孩子,再展开所有孩子。

懒加载全选

思路

1、既然是懒加载,那我们需要一个或者列表的接口,一个点击展开获取孩子的接口。
el-table有load属性,接受一个方法 resolve 孩子的值。

我的方法是写在组件里面的,相当于是用el-table 封装了一个table组件,不是直接用el-table

 /**
     *
     * @param {*} tree
     * @param {*} resolve
     *  懒加载获取孩子数据
     */
    async loadChildren(tree, treeNode, resolve) {
      const code = tree[this.rowKey]
      const { hasChildren = 'testcaseCount' } = this.tableOptions.treeProps || {}

      // 有懒加载的方法情况下  loadMethod  为load方法 ,单独点击展开键的时候的获取孩子的操作
      if (typeof this.loadMethod === 'function' && !this.isExpandAll) {
        const data = await this.loadMethod (tree) // 拿到孩子的值
      
        if (tree[hasChildren]) {
          const checked = this.isChecked(tree)  // 懒加载情况下判定孩子是否勾选
          data.forEach(item => {
            this.$refs.table.toggleRowSelection(item, !!checked)
          })
        }
        resolve(data)
        return
      }
      // 是已经打开了一键展开,说明已经获取过孩子,直接读取缓存
       resolve(this.tableKeyMap[code] || []) // 
      this.$nextTick(() => {
        this.expandChildren(this.tableKeyMap[code], code)
      })
    },
 	isChecked(row) {
 	// 判定点击展开获取孩子的这项是否在已选项中,这样判定是否需要复选
      return this.$refs.table.selection.some(item => item[this.rowKey] === row[this.rowKey])
    },
     /**
     *
     * @param {*} data
     * @param {*} code
     * 一键展开后的操作孩子数据
     */
    expandChildren(data, code) {
       for (const item of data) {
         if (item[hasChildren]) {
           const treeData = this.$refs.table.store.states.treeData // 可以打印出来看一下,可以拿到当前所有可展开的节点
           const code = item[this.rowKey]

           const els = document.querySelector(`.can-click${code}`) 
           if (!els) return
           els.click() // 模拟点击箭头展开操作,这样就会触发上面的 loadChildren 方法,去掉接口拿孩子的数据

           if (treeData[code]) {
             this.$set(treeData[code], 'lazy', false)
             treeData[code][children] = this.tableKeyMap[code] || []
           }
         }
       }
    },

2、 现在来实现一键展开操作
在这里插入图片描述

    /**
     * 一键展开功能
     */
    async handleExpandAll() {
        this.isExpandAll = !this.isExpandAll
        const treeData = this.$refs.table.store.states.treeData
        const keys = Object.keys(treeData)

        // 懒加载情况下
        if (this.tableOptions.lazy) {
          this.tableLoading = true
          if (typeof this.tableOptions.expandMethod === 'function' && this.isExpandAll) {
            const { data = [] } = await this.tableOptions.expandMethod()
          // 接口提供查询出所有孩子的数据,这是对于大数据的思路,直接resolve对于code的children。避开展开一个掉一次孩子查询接口
            this.setTableKeyMap(data)
          }
          keys.forEach(item => {
            if (treeData[item].expanded !== this.isExpandAll) {
              // 模拟点击展开
              if (this.isExpandAll) {
                const els = document.querySelector(`.can-click${item}`)
                if (!els) return
                els.click() 
              } else {
                // 收起
                this.$set(treeData[item], 'expanded', false)
              }

              this.$set(treeData[item], 'loading', false)
              treeData[item][children] = this.tableKeyMap[item] || []
            }
          })
          this.tableLoading = false
        } else {
          // 正常数据下直接展开,改属性
          keys.forEach(item => {
            this.$set(treeData[item], 'expanded', this.isExpandAll)
          })
        }
    },
     /**
     *
     * @param {*} list
     * 获取每个key值的孩子,存起来
     */
    setTableKeyMap(list) {
      for (const item of list) {
        if (Array.isArray(item.children)) {
          this.setTableKeyMap(item.children)
        }
        this.tableKeyMap[item[this.rowKey]] = item.children || []
      }
    },

3、还有一个需要解决的就是,展开的时候需要判定孩子是否需要勾选起来,根据展开的选项复选框来判定

   /**
     * 节点展开事件
     *
     * @description 通过 expandMap 记录展开的行
     * @param row 当前行
     * @param expanded 展开状态
     */
    onExpandChange(row, expanded) {
      expanded && this.handleReverseSelect(row, !!this.isChecked(row))
    },
     // 判断是否需要 选中孩子
    handleReverseSelect(row, expanded) {
      // 是懒加载
      if (this.tableOptions.lazy) {
        const children = this.tableKeyMap[row[this.rowKey]] || []
        if (children.length) {
          for (const item of children) {
            if (this.isChecked(item) === expanded) {
              return
            }
          }
          children.forEach(item => {
            this.$refs.table.toggleRowSelection(item, !!expanded)
          })
        }
      }
    },
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
实现 el-table 懒加载的一种方法是使用 el-table 的 load 方法。load 方法会在表格初始化时自动调用,以获取表格的初始数据。然后,您可以使用 load 方法来获取更多数据,并将其添加到表格中。 以下是一个简单的示例,演示了如何使用 load 方法来懒加载 el-table: ```html <template> <el-table :data="tableData" :load="loadData" height="300"> <el-table-column prop="name" label="Name"></el-table-column> <el-table-column prop="age" label="Age"></el-table-column> <el-table-column prop="address" label="Address"></el-table-column> </el-table> </template> <script> export default { data() { return { tableData: [], currentPage: 1, pageSize: 10 }; }, methods: { loadData() { // 获取数据的 API 接口 const API_URL = "https://api.example.com/users"; // 计算数据的偏移量和限制量 const offset = (this.currentPage - 1) * this.pageSize; const limit = this.pageSize; // 使用 axios 发送请求来获取数据 axios.get(API_URL, { params: { offset, limit } }).then(response => { // 将数据添加到表格中 this.tableData = this.tableData.concat(response.data); }); } }, created() { // 初始化数据 this.loadData(); } }; </script> ``` 在上面的示例中,loadData 方法使用 axios 库来发出 GET 请求,并使用偏移量和限制量参数(currentPage 和 pageSize)来获取数据。然后,它将响应数据添加到表格的现有数据中(使用 concat 方法)。最后,loadData 方法返回一个 Promise,以便表格可以在数据加载完成后刷新。 请注意,上面的代码只是一个示例,实际的实现可能需要更多的代码和逻辑来处理分页、过滤和排序等功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

那就可爱多一点点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值