项目的需求是给角色分配菜单,菜单会有子集,所以后台反给我的是带children的树形数据,但是添加的时候可能是一次性选很多的菜单,多选就不能直接用elemengt自带的多选,所以用了表格树形和复选框的组合,复选框用了插槽,完成了一些列的逻辑
表格部分
视图层
table中加入树形 :tree-props="{children: 'children'}"
插入两个复选框,一个是表头的,一个是表身
绑定对应的v-model,还有对应的事件,后边写对应的逻辑
<el-dialog title="菜单分配" append-to-body center show-close :visible.sync="dialogMenuVisible" @open="handleOpening" @close="handleClosing">
<el-table
ref="multipleTable"
:data="menuData"
style="width: 100%;margin-bottom: 20px;"
row-key="id"
border
:tree-props="{children: 'children'}"
>
<el-table-column width="105">
<template slot="header" slot-scope="scope">
<span>全选span>
<el-checkbox v-model="checkouts" style="padding-left:10px" @change="checkAllIn(scope)" />
template>
<template slot-scope="scope">
<el-checkbox v-model="scope.row.checks" style="padding-left:10px" @change="checkChange(scope.row)" />
template>
el-table-column>
<el-table-column
align="left"
prop="menuName"
label="菜单名称"
min-width="180"
:show-overflow-tooltip="isshow" />
<el-table-column
align="left"
prop="menuCode"
label="菜单编码"
min-width="240" />
el-table>
<el-row type="flex" justify="center">
<el-button type="primary" @click="menuSubmit">提交el-button>
<el-button type="primary" @click="resetSubmit">取消el-button>
el-row>
el-dialog>
逻辑层
因为是树形,所以遍历完父节点再遍历子节点(个人认为循环套循环不好,有更好方法请大神指教!!!)
v-model:checkouts
默认选中状态在data中声明false即可
checkouts: false,
//this.$refs.multipleTable.data是使用$ref获取注册的子组件信息,用data获取所有行,并用map函数遍历行
//使用$set的原因,是因为数组通过下标改变视图层不改变
// 总全选
checkAllIn() {
console.log(this.checkouts);
this.$refs.multipleTable.data.map((items) => {
console.log(items);
this.$set(items, "checks", this.checkouts)
if (items.children) {
items.children.forEach((item) => {
this.$set(item, "checks", this.checkouts)
})
}
});
},
1.列表父节点点击,其对应子节点选中
checkchange
是上边绑定事件判断当前改变后的值是true还是flase
2.子带父,点击子集复选框被点中true☑️,对应的父级也会变为true
menuData
是我掉菜单接口获取了平铺的树形结构后赋值给menudata这个数组,遍历这个数字,判断子父的联系,比如我这里是孩子的parentId和父元素的id是一样的,且父元素的parentid是“0”所以就这样判断的他们的关联
3.子空父空,当点击父元素其变为true时,子元素全部变为true,这时当把该父元素下所有子集点位false时,父元素变为false
思路是把其子元素放在一个空数组里,判断数组的长度是否等于零,如果等于
checkChange(row) {
console.log(row);
// 父选子
if (row.children) {
if (row.checks) {
console.log("panduanxuanzhong");
row.children.map((item) => {
this.$set(item, "checks", true)
});
this.$set(row, "checks", true)
} else {
console.log("未选中");
row.children.map((item) => {
this.$set(item, "checks", false)
});
this.$set(row, "checks", false)
}
}
// 子带父
if (row.checks) {
this.menuData.map(items => {
// console.log(item.parentId);
if (row.parentId === items.id && items.parentId === "0") {
this.$set(items, "checks", true)
}
})
return
}
// 子空父空
const son = []
if (!row.checks && row.parentId !== 0) {
this.menuData.map(ite => {
if (ite.children) {
ite.children.map(items => {
if (items.parentId === row.parentId && items.checks) {
son.push(items)
}
})
}
})
}
if (son.length === 0) {
this.menuData.map(item => {
if (item.id === row.parentId) {
this.$set(item, "checks", false)
}
})
}
console.log(son);
},
实现图如下
如有不对之处!!!欢迎大家指正!!!!!