el-table树形表格中复选框联动功能操作大全

 更新时间:2026年01月06日 09:55:18   作者:咩咩可以很温柔  
本文介绍了如何在el-table树形表格中实现复选框联动功能,包括父级复选框控制子级复选框状态以及子级复选框不可控制父级复选框状态的功能,通过给表格数据添加标识并编写相应的事件处理函数,实现了这一功能,感兴趣的朋友跟随小编一起看看吧

最终效果:

需求描述:

1.父级复选框可控制子级复选框状态:点击父级复选框选中或不选中时,子级复选框根据父级状态更新选中状态。

2.子级复选框不可控制父级复选框状态:子级复选框全选时,不会默认勾选父级复选框。父级全选后取消所有子级复选框,父级复选框状态不会改变。

解决方法:

我的思路是给table列表数据添加一个标识 (isCheck = false),通过点击复选框改变标识,再通过标识来控制复选框选中状态。

基础代码

        <el-table
          ref="treeTable"
          v-loading="loading"
          :data="tableList"
          row-key="id"
          stripe
          class="table_hei296"
          :expand-row-keys="expandRowKeys"
          @select="handleSelection"
          @select-all="selectAll"
          :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
        >
          <el-table-column type="selection" width="55" align="center" :selectable="handleSelectable"/>
          <el-table-column type="index" width="55" align="center" label="序号"/>
          <el-table-column prop="name" label="类名称" show-overflow-tooltip />
          <el-table-column prop="code" label="编码" show-overflow-tooltip />
          <el-table-column prop="groupType" label="组别" show-overflow-tooltip />
        </el-table>

1.初始化table列表数据。

    initCheckedBox() {
      const initList = function(data) {
        data.forEach(function(item) {
          item.isCheck = false // 未选中
          if (item.children) {
            initList(item.children)
          }
        })
        return data
      }
      this.rightCheckList = initList(this.tableList)
    },

2.当用户手动勾选全选 Checkbox 时触发的事件

    // 当用户手动勾选全选 Checkbox 时触发的事件
    selectAll(selection) {
      if (!this.checkAll) {
        this.checkAll = true
        this.isAllChecked(this.rightCheckList, true)
      } else {
        this.checkAll = false
        this.isAllChecked(this.rightCheckList, false)
      }
      const selectCheck = this.$getNodesIterative(this.rightCheckList, 'children', 'isCheck', true)
      this.selectedRows = selectCheck.map(item => item.id)
    },
    // 是否全选中
    isAllChecked(data, status) {
      if (data === undefined) {
        const imitData = []
        imitData.push(data)
      } else {
        data.forEach(item => {
          item.isCheck = item.parentId === 0 ? false : status
          this.$refs.treeTable.toggleRowSelection(item, item.isCheck)
          if (item.children) {
            this.isAllChecked(item.children, status)
          }
        })
      }
    },

checkAll默认false

3.当用户手动勾选数据行的 Checkbox 时触发的事件

     handleSelection(selection, row) {
      row.isCheck = !row.isCheck
      if(row.children.length === 0 && row.isCheck === true){
        this.checkedParentRow(row, this.rightCheckList)
      } else if(row.children.length === 0 && row.isCheck === false){
        this.clearParentRow(row, this.rightCheckList)
      } else if(row.children.length > 0 && row.isCheck === true){
        this.isAllChecked(row.children, true)
      } else if(row.children.length > 0 && row.isCheck === false){
        this.isAllChecked(row.children, false)
      }
      const selectCheck = this.$getNodesIterative(this.rightCheckList, 'children', 'isCheck', true)
      this.selectedRows = selectCheck.map(item => item.id)
    },
    // 选中子节点默认选中父节点,暂时不用,这段与需求不同,可不写。
    // 如果有这个需求可写,并取消if隐藏代码
    checkedParentRow(data, obj) {
      for(var item in obj){
        if(obj[item].id === data.parentId){
          var every = obj[item].children.every(function(item) {
            return item.isCheck === true
          })
          // if (every) {
          //   obj[item].isCheck = true
          //   this.$refs.treeTable.toggleRowSelection(obj[item], true)
          // }
        }
      }
    },
    // 子节点都未被选中,父节点默认取消选中
    clearParentRow(data, obj) {
      const parentRow = this.$findTreeObjById(obj, 'id', data.parentId)
      parentRow.isCheck = false
      this.$refs.treeTable.toggleRowSelection(parentRow, false)
    },

this.$getNodesIterative与this.$findTreeObjById写成了全局方法,如下:

/**
 *
 * @param {Array} treeList 树形数据
 * @param {string} targetType 树形数据中所查找的键值
 * @param {string} target 树形数据中所查找的值
 * @returns
 */
export function findTreeObjById(treeList, targetType, target) {
  for (const item of treeList) {
    // 匹配当前节点
    if (item[targetType] === target) return item;
    // 递归查找子节点
    if (item.children && item.children.length > 0) {
      const res = findTreeObjById(item.children, targetType, target);
      if (res) return res;
    }
  }
  return null; // 无匹配
}
/**
 * 提取树形结构中所有type为true的节点(迭代版,避免栈溢出)
 * @param {Array} tree 树形结构数组
 * @param {string} childrenKey 子节点字段名
 * @param {string} key 判断键值
 * @param  flagValue 判断键值
 * @returns {Array} 平级的符合条件的节点数组
 */
export function getNodesIterative(tree, childrenKey, key, flagValue) {
  const result = [];
  // 用栈存储待遍历的节点(初始为根节点数组)
  const stack = [...tree];
  while (stack.length > 0) {
    const node = stack.pop(); // 栈顶取出节点(也可用shift()实现队列,效率略低)
    // 筛选type为true的节点
    if (node[key] === flagValue) {
      result.push({ ...node });
    }
    // 子节点入栈(继续遍历)
    if (Array.isArray(node[childrenKey])) {
      stack.push(...node[childrenKey]);
    }
  }
  return result;
}
export default {
  findTreeObjById,
  getNodesIterative
}

总结:

这个功能两个项目中都用到了,所以记录下~

提醒自己:这段代码写了两三年了,没做优化,后面记得优化一下呀~

到此这篇关于el-table树形表格中,复选框联动功能的文章就介绍到这了,更多相关el-table复选框联动内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue获取HTMLCollection列表的children时结果为undefined问题

    Vue获取HTMLCollection列表的children时结果为undefined问题

    这篇文章主要介绍了Vue获取HTMLCollection列表的children时结果为undefined问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • vue elementui二次封装el-table带插槽问题

    vue elementui二次封装el-table带插槽问题

    这篇文章主要介绍了vue elementui二次封装el-table带插槽问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • VS Code打开vue文件出现很多黄色波浪线的完美解决办法

    VS Code打开vue文件出现很多黄色波浪线的完美解决办法

    作为一名经验丰富的开发者,下面这篇文章主要给大家介绍了关于VS Code打开vue文件出现很多黄色波浪线的完美解决办法,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2024-04-04
  • vue项目使用electron进行打包操作的全过程

    vue项目使用electron进行打包操作的全过程

    我们都知道Electron项目分为了主进程和渲染进程,主进程其实就是我们的Electron,渲染进程就相当于我们的Vue项目,下面这篇文章主要给大家介绍了关于vue项目使用electron进行打包操作的全过程,需要的朋友可以参考下
    2023-03-03
  • 在vue中读取本地Json文件的方法

    在vue中读取本地Json文件的方法

    今天小编就为大家分享一篇在vue中读取本地Json文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • Vue 3 响应式系统中ref 在 reactive 中的自动解包行为解析

    Vue 3 响应式系统中ref 在 reactive 中的自动解包行为

    Vue3中,ref与reactive配合使用时会自动解包,使代码更简洁,响应式系统更智能,替换ref会断开旧连接,浅层reactive/shallowRef不触发解包,但是需注意区分,下面通过示例给大家介绍Vue3响应式探秘:ref 在reactive中的自动解包行为解析,感兴趣的朋友一起看看吧
    2025-07-07
  • VUE mixin 使用示例详解

    VUE mixin 使用示例详解

    混入mixin提供了一种非常灵活的方式,来分发Vue组件中的可复用功能,一个混入对象可以包含任意组件选项,接下来通过本文给大家介绍VUE mixin 使用,需要的朋友可以参考下
    2022-08-08
  • Vue实现网页转PDF方法流程详解

    Vue实现网页转PDF方法流程详解

    在日常的工作中,有时候会碰到需要将某个网址网页保存成为pdf的情况,这篇文章主要介绍了用Vue实现网页转PDF的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • 基于vue的tab-list类目切换商品列表组件的示例代码

    基于vue的tab-list类目切换商品列表组件的示例代码

    这篇文章主要介绍了基于vue的tab-list类目切换商品列表组件的示例代码,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-02-02
  • vue中如何去掉空格的方法实现

    vue中如何去掉空格的方法实现

    这篇文章主要介绍了vue中如何去掉空格的方法实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11

最新评论