功能:点击全选时所有子级选中,点击子级时对应的所有父级要选中。
实现思路:通过递归将所有子级转化为一级,选中时将选中的ID存为一个二级数组。循环时判断当前项在选中的数组中存在时即为勾选状态。
1、所有子级选中:通过递归的形式查找所有子级并且将它保存为一个二维数组,只保存ID即可。this.selectList = [{id:1},{id:2}]
2、所有父级选中:选择某个子级时判断是否有父级,有父级则将所有父级选中,这时候就用到我们一开始的树形结构转化的一级所有节点。
具体代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>VUE实现三级权限复选框</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<style>
* {
padding: 0px;
padding: 0px;
}
body {
font-size: 12px;
}
</style>
</head>
<body>
<div id="app">
<div><input type="checkbox" :checked="selectIds.length==allData.length" @change="checkAll"> 全选 </div>
<div v-for="item in data" :key="item.id">
<input type="checkbox" :checked="selectIds.some(res=>res.id==item.id)" @change="toggleCheckbox(item)">
<label>{{ item.name }}</label>
<div style="padding-left:20px;" v-if="item.children">
<div v-for="child in item.children" :key="child.id">
<input type="checkbox" :checked="selectIds.some(res=>res.id==child.id)" @change="toggleCheckbox(child)">
<label>{{ child.name }}</label>
<div style="display:flex;" v-if="child.children">
<div style="margin-left:20px;" v-for="grandChild in child.children" :key="grandChild.id">
<input type="checkbox" :checked="selectIds.some(res=>res.id==grandChild.id)" @change="toggleCheckbox(grandChild)">
<label>{{ grandChild.name }}</label>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
data: [
{
name: '用户管理',
id: 1,
parentId: 0,
children: [
{
id: 2,
name: '用户列表',
parentId: 1,
children: [
{
id: 3,
name: '添加',
parentId: 2
},
{
id: 4,
name: '删除',
parentId: 2
},
{
id: 5,
name: '禁用',
parentId: 2
}
]
},
{
id: 6,
name: '积分列表',
parentId: 1,
children: [
{
id: 7,
name: '添加',
parentId: 6
},
{
id: 8,
name: '删除',
parentId: 6
},
]
}
]
},
{
name: '课程管理',
id: 9,
parentId: 0,
children: [
{
id: 10,
name: '课程列表',
parentId: 9,
children: [
{
id: 11,
name: '添加',
parentId: 10
},
{
id: 12,
name: '删除',
parentId: 10
},
{
id: 13,
name: '禁用',
parentId: 10
}
]
},
{
id: 14,
name: '课程订单',
parentId: 9,
children: [
{
id: 15,
name: '添加',
parentId: 14
},
{
id: 16,
name: '删除',
parentId: 14
},
]
}
]
}
],
allData: [],
selectIds: [],
},
mounted() {
this.getAlldata(this.data);
},
methods: {
//全部转化为一级
getAlldata(arr) {
arr.forEach(res => {
this.allData.push(res)
if (res.children) {
this.getAlldata(res.children)
}
})
},
//全选
checkAll() {
let all = this.allData.length == this.selectIds.length
if (!all) {
this.selectIds = this.allData.map(res => { return { id: res.id }; })
} else {
this.selectIds = []
}
},
//选中
toggleCheckbox(item) {
let index = this.selectIds.findIndex(res => { return res.id == item.id })
let flag = false
if (index == -1) {
this.selectIds.push({ id: item.id })
flag = true
} else {
this.selectIds.splice(index, 1)
}
if (item.children) {
this.toggleChildren(item, flag);
}
if (item.parentId!=0) {
this.toggleParents(item.parentId);
}
},
//所有子级选中
toggleChildren(item, flag) {
item.children.forEach((child, inx) => {
if(flag){
let index = this.selectIds.findIndex(res=>{ return res.id==child.id})
if(index==-1){
this.selectIds.push({id:child.id})
}
}else{
this.selectIds.forEach((res,index)=>{
if(res.id==child.id){ this.selectIds.splice(index, 1); }
})
}
if (child.children) {
this.toggleChildren(child, flag);
}
});
},
//选中子级时递归查找父级选中
toggleParents(parentId) {
let arr = this.allData
for (let i = 0; i < arr.length; i++) {
if (arr[i].id == parentId) {
let index = this.selectIds.findIndex(res => { return res.id == arr[i].id })
if (index == -1) { this.selectIds.push({ id: arr[i].id }); }
if (arr[i].children) {
this.toggleParents(arr[i].parentId)
}
}
}
},
}
});
</script>
</body>
</html>