1.效果
2.代码
menuData是表格数据,menuIds选中项id
<template>
<div class="home">
<a-button type="primary" @click="handleSave">
保存
</a-button>
<!-- 标题 -->
<div class="header-box">
<div class="first_menu_con">菜单</div>
<div class="second_menu_con">页面</div>
<div class="third_menu_con">按钮</div>
</div>
<!-- 内容 -->
<div class="body-box">
<div v-for="(firstItem,i) in menuData" :key="firstItem.id" class="tr-box">
<div class="first_con">
<a-checkbox :indeterminate="firstItem.indeterminate" v-model="firstItem.checkAll"
@change="firstCheckAll(firstItem,i)">
{{ firstItem.title }}
</a-checkbox>
</div>
<div class="second_con" v-if="firstItem.hasChildren">
<div v-for="(secondItem,secondI) in firstItem.children" :key="secondItem.id" class="second-tr">
<div class="second_box">
<a-checkbox :indeterminate="secondItem.indeterminate" v-model="secondItem.checkAll"
@change="secondCheckAll(firstItem,secondItem,secondI)">
{{ secondItem.title }}
</a-checkbox>
</div>
<div class="third_con" v-if="secondItem.hasChildren">
<a-checkbox-group v-model="secondItem.thirdcheckedValues"
@change="thirdChecked(firstItem,secondItem,$event)">
<a-checkbox v-for="(thirdItem, index) in secondItem.children" :key="thirdItem.id" :value="thirdItem.id">
{{ thirdItem.title }}
</a-checkbox>
</a-checkbox-group>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Home',
data() {
return {
menuData: [
{
"id": "1123598815738675201",
"parentId": "0",
"children": [
{
"id": "1123598815738675202",
"parentId": "1123598815738675201",
"children": [
{
"id": "1123598815738675219",
"parentId": "1123598815738675202",
"hasChildren": false,
"title": "新增",
"key": "1123598815738675219",
"value": "1123598815738675219"
},
{
"id": "1123598815738675220",
"parentId": "1123598815738675202",
"hasChildren": false,
"title": "修改",
"key": "1123598815738675220",
"value": "1123598815738675220"
},
{
"id": "1123598815738675221",
"parentId": "1123598815738675202",
"hasChildren": false,
"title": "删除",
"key": "1123598815738675221",
"value": "1123598815738675221"
},
{
"id": "1123598815738675222",
"parentId": "1123598815738675202",
"hasChildren": false,
"title": "查看",
"key": "1123598815738675222",
"value": "1123598815738675222"
}
],
"hasChildren": true,
"title": "通知公告",
"key": "1123598815738675202",
"value": "1123598815738675202"
}
],
"hasChildren": true,
"title": "工作台",
"key": "1123598815738675201",
"value": "1123598815738675201"
},
{
"id": "1123598815738675280",
"parentId": "0",
"children": [
{
"id": "1123598815738675281",
"parentId": "1123598815738675280",
"children": [
{
"id": "1123598815738675282",
"parentId": "1123598815738675281",
"hasChildren": false,
"title": "发起",
"key": "1123598815738675282",
"value": "1123598815738675282"
},
{
"id": "1123598815738675283",
"parentId": "1123598815738675281",
"hasChildren": false,
"title": "流程图",
"key": "1123598815738675283",
"value": "1123598815738675283"
}
],
"hasChildren": true,
"title": "发起事务",
"key": "1123598815738675281",
"value": "1123598815738675281"
},
{
"id": "1123598815738675284",
"parentId": "1123598815738675280",
"children": [
{
"id": "1123598815738675285",
"parentId": "1123598815738675284",
"hasChildren": false,
"title": "签收",
"key": "1123598815738675285",
"value": "1123598815738675285"
},
{
"id": "1123598815738675286",
"parentId": "1123598815738675284",
"hasChildren": false,
"title": "详情",
"key": "1123598815738675286",
"value": "1123598815738675286"
},
{
"id": "1123598815738675287",
"parentId": "1123598815738675284",
"hasChildren": false,
"title": "跟踪",
"key": "1123598815738675287",
"value": "1123598815738675287"
}
],
"hasChildren": true,
"title": "待签事务",
"key": "1123598815738675284",
"value": "1123598815738675284"
},
{
"id": "1123598815738675288",
"parentId": "1123598815738675280",
"children": [
{
"id": "1123598815738675289",
"parentId": "1123598815738675288",
"hasChildren": false,
"title": "办理",
"key": "1123598815738675289",
"value": "1123598815738675289"
},
{
"id": "1123598815738675290",
"parentId": "1123598815738675288",
"hasChildren": false,
"title": "详情",
"key": "1123598815738675290",
"value": "1123598815738675290"
},
{
"id": "1123598815738675291",
"parentId": "1123598815738675288",
"hasChildren": false,
"title": "跟踪",
"key": "1123598815738675291",
"value": "1123598815738675291"
}
],
"hasChildren": true,
"title": "待办事务",
"key": "1123598815738675288",
"value": "1123598815738675288"
},
{
"id": "1123598815738675292",
"parentId": "1123598815738675280",
"children": [
{
"id": "1123598815738675293",
"parentId": "1123598815738675292",
"hasChildren": false,
"title": "详情",
"key": "1123598815738675293",
"value": "1123598815738675293"
},
{
"id": "1123598815738675294",
"parentId": "1123598815738675292",
"hasChildren": false,
"title": "跟踪",
"key": "1123598815738675294",
"value": "1123598815738675294"
}
],
"hasChildren": true,
"title": "已发事务",
"key": "1123598815738675292",
"value": "1123598815738675292"
},
{
"id": "1123598815738675295",
"parentId": "1123598815738675280",
"children": [
{
"id": "1123598815738675296",
"parentId": "1123598815738675295",
"hasChildren": false,
"title": "详情",
"key": "1123598815738675296",
"value": "1123598815738675296"
},
{
"id": "1123598815738675297",
"parentId": "1123598815738675295",
"hasChildren": false,
"title": "跟踪",
"key": "1123598815738675297",
"value": "1123598815738675297"
}
],
"hasChildren": true,
"title": "办结事务",
"key": "1123598815738675295",
"value": "1123598815738675295"
}
],
"hasChildren": true,
"title": "我的事务",
"key": "1123598815738675280",
"value": "1123598815738675280"
},
{
"id": "1123598815738675210",
"parentId": "0",
"children": [
{
"id": "1123598815738675211",
"parentId": "1123598815738675210",
"hasChildren": false,
"title": "接口文档",
"key": "1123598815738675211",
"value": "1123598815738675211"
},
{
"id": "1123598815738675213",
"parentId": "1123598815738675210",
"children": [
{
"id": "1123598815738675214",
"parentId": "1123598815738675213",
"children": [
{
"id": "1123598815738675249",
"parentId": "1123598815738675214",
"hasChildren": false,
"title": "查看",
"key": "1123598815738675249",
"value": "1123598815738675249"
}
],
"hasChildren": true,
"title": "通用日志",
"key": "1123598815738675214",
"value": "1123598815738675214"
},
{
"id": "1123598815738675215",
"parentId": "1123598815738675213",
"children": [
{
"id": "1123598815738675250",
"parentId": "1123598815738675215",
"hasChildren": false,
"title": "查看",
"key": "1123598815738675250",
"value": "1123598815738675250"
}
],
"hasChildren": true,
"title": "接口日志",
"key": "1123598815738675215",
"value": "1123598815738675215"
},
{
"id": "1123598815738675216",
"parentId": "1123598815738675213",
"children": [
{
"id": "1123598815738675251",
"parentId": "1123598815738675216",
"hasChildren": false,
"title": "查看",
"key": "1123598815738675251",
"value": "1123598815738675251"
}
],
"hasChildren": true,
"title": "错误日志",
"key": "1123598815738675216",
"value": "1123598815738675216"
}
],
"hasChildren": true,
"title": "日志管理",
"key": "1123598815738675213",
"value": "1123598815738675213"
}
],
"hasChildren": true,
"title": "系统监控",
"key": "1123598815738675210",
"value": "1123598815738675210"
},
{
"id": "1123598815738675217",
"parentId": "0",
"children": [
{
"id": "1123598815738675218",
"parentId": "1123598815738675217",
"children": [
{
"id": "1123598815738675252",
"parentId": "1123598815738675218",
"hasChildren": false,
"title": "新增",
"key": "1123598815738675252",
"value": "1123598815738675252"
},
{
"id": "1123598815738675253",
"parentId": "1123598815738675218",
"hasChildren": false,
"title": "修改",
"key": "1123598815738675253",
"value": "1123598815738675253"
},
{
"id": "1123598815738675254",
"parentId": "1123598815738675218",
"hasChildren": false,
"title": "删除",
"key": "1123598815738675254",
"value": "1123598815738675254"
},
{
"id": "1123598815738675255",
"parentId": "1123598815738675218",
"hasChildren": false,
"title": "查看",
"key": "1123598815738675255",
"value": "1123598815738675255"
}
],
"hasChildren": true,
"title": "代码生成",
"key": "1123598815738675218",
"value": "1123598815738675218"
},
{
"id": "1161272593873321991",
"parentId": "1123598815738675217",
"children": [
{
"id": "1161272593873321992",
"parentId": "1161272593873321991",
"hasChildren": false,
"title": "新增",
"key": "1161272593873321992",
"value": "1161272593873321992"
},
{
"id": "1161272593873321993",
"parentId": "1161272593873321991",
"hasChildren": false,
"title": "修改",
"key": "1161272593873321993",
"value": "1161272593873321993"
},
{
"id": "1161272593873321994",
"parentId": "1161272593873321991",
"hasChildren": false,
"title": "删除",
"key": "1161272593873321994",
"value": "1161272593873321994"
},
{
"id": "1161272593873321995",
"parentId": "1161272593873321991",
"hasChildren": false,
"title": "查看",
"key": "1161272593873321995",
"value": "1161272593873321995"
}
],
"hasChildren": true,
"title": "数据源管理",
"key": "1161272593873321991",
"value": "1161272593873321991"
},
{
"id": "1161272593873321996",
"parentId": "1123598815738675217",
"hasChildren": false,
"title": "数据模型设计",
"key": "1161272593873321996",
"value": "1161272593873321996"
}
],
"hasChildren": true,
"title": "研发工具",
"key": "1123598815738675217",
"value": "1123598815738675217"
},
{
"id": "1164733399669962301",
"parentId": "0",
"children": [
{
"id": "1164733399669962302",
"parentId": "1164733399669962301",
"hasChildren": false,
"title": "报表配置",
"key": "1164733399669962302",
"value": "1164733399669962302"
},
{
"id": "1164733399669962303",
"parentId": "1164733399669962301",
"hasChildren": false,
"title": "报表列表",
"key": "1164733399669962303",
"value": "1164733399669962303"
},
{
"id": "1164733399669962304",
"parentId": "1164733399669962301",
"hasChildren": false,
"title": "公告报表",
"key": "1164733399669962304",
"value": "1164733399669962304"
}
],
"hasChildren": true,
"title": "报表管理",
"key": "1164733399669962301",
"value": "1164733399669962301"
}
],
menuIds: ['1123598815738675281', '1123598815738675282', '1123598815738675283', '1123598815738675286', '1123598815738675214', '1123598815738675252', '1123598815738675254', '1123598815738675255']
}
},
components: {},
mounted() {
},
created() {
this.getMenuData()
},
methods: {
// 获取数据并回显选中项
getMenuData() {
this.disableTreeNodes(this.menuData, this.menuIds)
console.log(this.menuData, 'menuDatas')
this.menuData.forEach(first => {
if (first.choosed) {
// 一级全选了
// 二三级也全选
first.indeterminate = false
first.checkAll = true
if (first.children && first.children.length) {
first.children.forEach(second => {
second.indeterminate = false
second.checkAll = true
if (second.children && second.children.length) {
second.thirdcheckedValues = second.children.map(item => item.id)
}
})
}
} else {
// 一级未选中
const secondChildLen = first.children.length
const secondCheckedLen = first.children.filter(item => item.choosed).length
if (first.children && first.children.length) {
// 有二级
first.children.forEach(second => {
if (second.children && second.children.length) {
// 有三级
const thirdLen = second.children.length
const thirdCheckedLen = second.children.filter(item => item.choosed).length
if (thirdCheckedLen == 0) {
// 三级全未选中
second.thirdcheckedValues = []
second.indeterminate = false
second.checkAll = false
const seCheckedLen = first.children.filter(item => !item.choosed && !item.indeterminate).length
if (seCheckedLen == secondChildLen) {
// 二级全未选
first.checkAll = false
first.indeterminate = false
} else {
first.checkAll = false
first.indeterminate = true
}
} else if (thirdCheckedLen == thirdLen) {
// 三级全选
second.indeterminate = false
second.checkAll = true
let thirdList = second.children.filter(item => item.choosed)
second.thirdcheckedValues = thirdList.map(i => i.id)
first.checkAll = false
first.indeterminate = true
} else {
let thirdList = second.children.filter(item => item.choosed)
second.thirdcheckedValues = thirdList.map(i => i.id)
first.checkAll = false
first.indeterminate = true
second.indeterminate = true
second.checkAll = false
}
} else {
// 没有三级
if (second.choosed) {
second.checkAll = true
} else {
second.checkAll = false
}
second.indeterminate = false
const seCheckedLen = first.children.filter(item => !item.choosed && !item.indeterminate).length
if (seCheckedLen == secondChildLen) {
// 二级全未选
first.checkAll = false
first.indeterminate = false
} else {
first.checkAll = false
first.indeterminate = true
}
}
})
} else {
// 没有二级
first.checkAll = false
first.indeterminate = false
}
}
})
this.$forceUpdate()
},
disableTreeNodes(treeData, idArray) {
if (!Array.isArray(treeData)) {
return;
}
for (const node of treeData) {
console.log(node, 'nodes')
if (idArray.includes(node.id)) {
node.choosed = true;
this.disableTreeNodes(node.children, idArray);
} else {
node.choosed = false;
if (Array.isArray(node.children)) {
this.disableTreeNodes(node.children, idArray);
}
}
}
},
// 选择一级
firstCheckAll(item, i) {
console.log(item, 'item')
item.indeterminate = false
if (item.checkAll) {
// 全选
if (item.children && item.children.length) {
item.children.forEach(second => {
second.indeterminate = false
second.checkAll = true
if (second.children && second.children.length) {
second.thirdcheckedValues = second.children.map(i => i.id)
} else {
second.thirdcheckedValues = []
}
})
}
} else {
// 全不选
if (item.children && item.children.length) {
item.children.forEach(second => {
second.indeterminate = false
second.checkAll = false
second.thirdcheckedValues = []
})
}
}
this.$forceUpdate()
},
// 选择二级
secondCheckAll(firstItem, item, i) {
console.log(firstItem, item, 'er')
item.indeterminate = false
const secondChildLen = firstItem.children.length
const secondCheckedLen = firstItem.children.filter(item => item.checkAll && !item.indeterminate).length
console.log(secondCheckedLen, 'secondCheckedLen00')
if (item.checkAll) {
console.log(1)
// 选中
if (secondChildLen == secondCheckedLen) {
// 二级全部选中了
firstItem.checkAll = true
firstItem.indeterminate = false
} else {
// 选中了部分
firstItem.checkAll = false
firstItem.indeterminate = true
}
if (item.children && item.children.length) {
item.thirdcheckedValues = item.children.map(i => i.id)
}
} else {
console.log(2)
// 取消选中
const seCheckedLen = firstItem.children.filter(item => !item.checkAll && !item.indeterminate).length
console.log(seCheckedLen, 'seCheckedLen')
if (seCheckedLen == secondChildLen) {
// 二级全部都未选中
firstItem.checkAll = false
firstItem.indeterminate = false
} else {
firstItem.checkAll = false
firstItem.indeterminate = true
}
if (item.children && item.children.length) {
item.thirdcheckedValues = []
}
}
this.$forceUpdate()
},
// 选择三级
thirdChecked(firstItem, secondItem, e) {
console.log(secondItem, e, 'item')
const thirdChildLen = secondItem.children.length
const secondChildLen = firstItem.children.length
if (secondItem.thirdcheckedValues.length == 0) {
// 三级全未选中 二级修改成未选中
secondItem.checkAll = false
secondItem.indeterminate = false
const secondNoCheckedLen = firstItem.children.filter(item => !item.checkAll && !item.indeterminate).length
if (secondChildLen == secondNoCheckedLen) {
// 二级全未选中
firstItem.checkAll = false
firstItem.indeterminate = false
} else {
firstItem.checkAll = false
firstItem.indeterminate = true
}
} else if (secondItem.thirdcheckedValues.length == thirdChildLen) {
// 三级全部选中
secondItem.checkAll = true
secondItem.indeterminate = false
const secondCheckedLen = firstItem.children.filter(item => item.checkAll).length
if (secondChildLen == secondCheckedLen) {
// 二级全部选中了
firstItem.checkAll = true
firstItem.indeterminate = false
} else {
// 选中了部分
firstItem.checkAll = false
firstItem.indeterminate = true
}
} else {
// 三级选中了一部分
secondItem.checkAll = false
secondItem.indeterminate = true
firstItem.checkAll = false
firstItem.indeterminate = true
}
this.$forceUpdate()
},
findAncestorsById(tree, result = []) {
if (!Array.isArray(tree)) {
return;
}
for (const node of tree) {
if (node.checkAll) {
result.push(node.id);
}
if(node.thirdcheckedValues && node.thirdcheckedValues.length){
result.push(...node.thirdcheckedValues)
}
if (node.children && node.children.length) {
this.findAncestorsById(node.children, result);
}
}
return result;
},
// 保存
handleSave() {
console.log(this.menuData, 'menuDatas')
console.log(this.findAncestorsById(this.menuData),'33')
},
},
}
</script>
<style scoped>
.home {
width: 90%;
margin: 40px auto;
}
.header-box {
display: flex;
align-items: center;
text-align: left;
background: #fafafa;
border-bottom: 1px solid #e8e8e8;
border-top: 1px solid #e8e8e8;
border-right: 1px solid #e8e8e8;
color: rgba(0, 0, 0, .85);
font-weight: 600;
}
.first_menu_con {
width: 14%;
border-left: 1px solid #e8e8e8;
padding: 16px;
}
.second_menu_con {
width: 14%;
border-left: 1px solid #e8e8e8;
padding: 16px;
}
.third_menu_con {
width: 72%;
border-left: 1px solid #e8e8e8;
padding: 16px;
}
.tr-box {
display: flex;
align-items: center;
text-align: left;
border-bottom: 1px solid #e8e8e8;
border-left: 1px solid #e8e8e8;
}
.first_con {
width: 14%;
padding: 0 16px;
box-sizing: border-box;
}
.second_con {
width: 86%;
}
.second_box {
width: 16.27%;
border-left: 1px solid #e8e8e8;
border-right: 1px solid #e8e8e8;
padding: 16px;
box-sizing: border-box;
}
.third_con {
width: 84%;
padding: 16px;
box-sizing: border-box;
}
.second-tr {
display: flex;
align-items: center;
border-bottom: 1px solid #e8e8e8;
border-right: 1px solid #e8e8e8;
}
.second_con .second-tr:nth-last-child(1) {
border-bottom: none;
}
</style>