el-table多级嵌套列表,菜单使用el-switch代替

需求:根据el-table实现多级菜单复选,并且只要是菜单就不再有复选框,也没有全选按钮,一级菜单使用el-switch代替原有的列复选框,子级如果全部选中,那么父级的el-switch也会被选中,如下图,注意:这样写是没有列头的,列头的全选按钮一直获取不到它的checked的值,试了很多种还是不行,全选按钮只能全选反选实现不了,放弃了。

 1.后端数据

  1. 一定要后端给每个级别的菜单还有增删改查功能项都添加个checked:false
  2. 后端一定要用type或者是什么表示是菜单还是功能项
  3. 后端数据如下,多级的列表,type为0表菜单,为1表功能项
"data": [
		{
			"menu_id": 1,
			"menu_name": "仪表盘",
			"type": 0,
			"checked": false,
			"children": [
				{
					"menu_id": 17,
					"menu_name": "查看",
					"type": 1,
					"checked": false
				}
			]
		},
{
			"menu_id": 1,
			"menu_name": "用户管理",
			"type": 0,
			"checked": false,
			"children": [
				{
					"menu_id": 17,
					"menu_name": "查看",
					"type": 1,
					"checked": false,
                    "children": [
						{
							"menu_id": 31,
							"menu_name": "设备连接拓扑图隐藏或显示",
							"type": 1,
							"checked": false
						},
				}
			]
		},

2.el-table表格实现

  1. :data就是后端的数据
  2. row-key:行数据的key值,要是唯一值,不然报错
  3. :show-header=false不展示表头

  4. :tree-props="{ children: 'children', hasChildren: 'hasChildren' }",渲染嵌套数据的默认配置,通俗点就是,判断有没有children有就下一级自动渲染

  5. 主要是看第一个el-table-column的 type="selection"属性,这个属性就是添加复选框了,之后使用插槽的方式只要是type为0功能项才会添加el-checkbox复选框按钮,type为1的才是el-switch开关控制

       <el-table
            :data="tableData"
            row-key="menu_id"
            style="width: 100%"
            :show-header="false"
            :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
          >
            <el-table-column
              type="selection"
              :selectable="selectable"
              width="50"
            >
              <template slot-scope="{ row }">
                <span v-if="row.type === 0"></span>
                <el-checkbox
                  v-model="row.checked"
                  v-else
                  @change="handleCheck(row.menu_id, row.checked, row)"
                ></el-checkbox>
              </template>
            </el-table-column>
            <el-table-column prop="menu_name" label="菜单" align="left">
            </el-table-column>
            <el-table-column label="操作" align="center">
              <template slot-scope="scope" v-if="scope.row.type == 0">
                <el-switch
                  v-model="scope.row.checked"
                  active-color="#13ce66"
                  inactive-text="全选"
                  @change="swictchange($event, scope.row)"
                >
                </el-switch>
              </template>
            </el-table-column>
          </el-table>

3.多级嵌套表单-单选-反选el-switch

如果子级的功能项都选中了那么直接反选子级的上一级的el-switch的开关,这边建议直接复制

这边传入的tabledata就是所有的数据,使用递归的方式实现的反选switch

 // 点击单行获取到数据,实现反选
    handleCheck() {
      this.setHandleCheck(this.tableData);
    },
    setHandleCheck(menuList) {
      // checked变量初始化为true
      let checked = true;
      // 遍历菜单列表的每一个菜单,
      for (let i = 0; i < menuList.length; i++) {
        // []中的每一个对象存储在menu
        const menu = menuList[i];
        // 如果菜单中有子菜单,那么就递归重新调用菜单来更新子菜单的checked属性
        if (menu.children && menu.children.length > 0) {
          menu.checked = this.setHandleCheck(menu.children);
        }
        // 判断初始值和menu.checked的值是否为ture
        checked = checked && menu.checked;
      }
      return checked;
    },

4.el-switch控制全选子级,子级单选没选完之后再点击switch会全选

    // 开关状态
    swictchange(flag, row) {
      this.setLastRight(row, this.menulistReq, flag);
      console.log(this.menulistReq, "递归得到的值");
      this.setHandleCheck(this.tableData);
    },
    // 递归全选
    setLastRight(obj, arr, flag) {
      if (!obj.children) {
        return;
      }
      // 当前对象要是没有children,就遍历children
      obj.children.forEach((item) => {
        item.checked = flag;
        // 传递俩个实参,item在一二级都是有chilren,所以会一直调用到最后一级,最后一级是没呀chiren
        this.setLastRight(item, arr, flag);
      });
    }

5.提交权限

这样就实现多级全选反选了,最后用el-button按钮提交权限,接口什么的每个人封装的不一样哈,写法可能有点出入,我在提交的时候是提交menu_id,只需要在最后遍历一遍表格数据,根据checked为true的吧menu_id添加到数组就行了,之后再传给后端

    // 分配角色权限
    async allotPermission() {
      this.recursionChecedTrue(this.tableData);
  const menu = [...new Set(this.menulistReq)];
      const res = await SetRoleManage({
        menu_ids: menu,
        id: this.copyrole.id_1,
      });
      if (res.code == 200) {
        this.$message.success("角色分配成功");
      }
    },
    // 递归获取所有checked为ture的值
    recursionChecedTrue(tableData) {
      tableData.forEach((item) => {
        if (item.checked) {
          this.menulistReq.push(item.menu_id);
        }
        if (item.children) {
          this.recursionChecedTrue(item.children);
        }
      });
    },

文章到此结束,希望对你有所帮助~~

猜你喜欢

转载自blog.csdn.net/qq_44278289/article/details/130623626