a-tree 组件实现折叠选择;使其父级节点禁用,通过子级节点的勾选状态来控制是否勾选;如果子级节点勾选任一个,父级节点就勾选中,如果子级节点全部不勾选则父节点不勾选,否则勾选 ,效果如下:
代码实现如下所示:
1、封装组件 setTableToolbar
vue 部分
<template>
<div class="toolbar-meta">
<vxe-pulldown ref="vxePulldown" transfer @hide-panel="hidePanel">
<template #default>
<a-button shape="circle" @click="open()" :size="16">
<vxe-icon style="font-size: 20px;" name="setting"></vxe-icon>
</a-button>
</template>
<template #dropdown>
<div class="downBox" >
<!-- <div class="checkTopAll">
<a-checkbox
v-model="checkAll"
@change="onCheckAllChange"
>全部
</a-checkbox>
</div> -->
<div class="checkItem">
<a-tree
v-if="plainOptions.length>0"
checkable
:checkStrictly="true"
:tree-data="plainOptions"
:expandedKeys="expandedKeys"
:checkedKeys="checkedList"
:replace-fields="{children: 'children', title: 'title', key: 'id'}"
@expand="onExpand"
@check="checkNode"
/>
</div>
<!-- 底部按钮 -->
<div class="downBtn clearfix">
<a-button class="btnOk" @click="sumbitOk">确认</a-button>
<a-button class="btnReset" @click="sumbitReset">全选</a-button>
</div>
</div>
</template>
</vxe-pulldown>
</div>
</template>
js部分代码设置:
export default {
name: 'setTableToolbar',
components: {
},
props: {
columns: {
type: Array,
default: [],
}
},
data(){
return {
expandParent: true,
expandedKeys: [],
indeterminate: true,
userInfo: {},
checkAll: false,
checkedList: [],
plainOptions: [],
Downtype: false
}
},
watch: {
checkedList() { // 监听设置
this.isCheckedAll()
},
},
methods:{
open(){
this.$refs.vxePulldown.togglePanel()
if(this.Downtype){
this.sumbitOk()
// this.$refs.vxePulldown.hidePanel()
} else {
this.Downtype = !this.Downtype
}
},
// 隐藏 执行保存
hidePanel(){
this.sumbitOk()
},
// 父级节点展开、收缩事件
onExpand(select, e){
let val = e.node.eventKey || ''
if(this.expandedKeys.indexOf(val) > -1) {
this.expandedKeys.splice(this.expandedKeys.indexOf(val), 1)
} else {
this.expandedKeys.push(val)
}
},
//
/**
* 初始设置
* @param {*} arr 所有选择项
* @param {*} selearr 已选择项
* @param {*} info 用户信息 保存使用
*/
resetListLable(arr, selearr, info){
this.userInfo = info || {}
let plainOptions = []
arr.forEach((item, i) => {
if(item.title&&item.dataIndex&&item.dataIndex != 'action'){
item.id = item.dataIndex
item.key = '0-'+i
if(item.children && item.children.length>0){
item.disabled = true
item.children.forEach((itm,u)=>{
itm.id = itm.dataIndex ? itm.dataIndex : 'p-'+i +'-'+u
itm.key = '0-'+i +'-'+u
if(itm.children&&itm.children.length>0){
itm.disabled = true
itm.children.forEach((imt,ui)=>{
imt.id= imt.dataIndex ? imt.dataIndex : 'p-'+i +'-'+u+'-'+ui
imt.key = '0-'+i +'-'+u+'-'+ui
})
}
})
}
plainOptions.push(item)
}
});
this.plainOptions = plainOptions
let seletOption = []
if(selearr){
selearr.forEach(itm => {
if(itm.title&&itm.dataIndex&&itm.dataIndex != 'action'){
let objItem = itm.dataIndex
seletOption.push(objItem)
if(itm.children&&itm.children.length>0){
itm.children.forEach(itm2=>{
seletOption.push(itm2.dataIndex)
if(itm2.children&&itm2.children.length>0){
itm2.children.forEach(itm3=>{
seletOption.push(itm3.dataIndex)
})
}
})
}
}
});
}
this.checkedList = seletOption
},
//选择点击
checkNode(check, e){
this.checkedList = e.checkedNodes && e.checkedNodes.length>0 ? e.checkedNodes.map(x=>{return x.key}) : []
this.parentCheckNode(check, e)
},
// 判断是否选择父节点
parentCheckNode(check, e){
this.plainOptions.forEach((item,u)=>{
if(this.checkedList.indexOf(item.id) > -1) {
let isHaveParent = true
// 查子节点内是否
if(e.checked == false && item.children && item.children.length>0){
item.children.forEach((itm,b)=>{
if(this.checkedList.indexOf(itm.id) > -1) {
let isPHaveParent = true
if(e.checked == false && itm.children && itm.children.length>0){
itm.children.forEach(itm2=>{
if(this.checkedList.indexOf(itm2.id) > -1) {
isPHaveParent = false
return
}
})
if(isPHaveParent == true){
this.checkedList.splice(this.checkedList.indexOf(itm.id), 1)
return
}
} else {
isHaveParent = false
return
}
}
})
if(isHaveParent == true){
this.checkedList.splice(this.checkedList.indexOf(item.id), 1)
return
}
} else {
return
}
return
} else {
if(item.children && item.children.length>0){
item.children.forEach((itm,b)=>{
if(this.checkedList.indexOf(itm.id) > -1) {
this.checkedList.push(item.id)
return
} else {
if(itm.children&&itm.children.length>0){
itm.children.forEach((imt,ui)=>{
if(this.checkedList.indexOf(imt.id) > -1) {
this.checkedList.push(item.id)
this.checkedList.push(imt.id)
return
}
})
}
}
})
}
}
})
},
// 查看点击事件
selectNode(selectkey, e){
let node_eventKey = e.node.eventKey || ''
this.param = {
id: node_eventKey,
title: e.node.title || '',
}
this.selectKeys = [node_eventKey]
},
// 全选设置
onCheckAllChange(e){
let newList = []
if(e.target.checked){
this.plainOptions.forEach(item =>{
newList.push(item.dataIndex)
})
}
this.checkedList = newList
this.isCheckedAll()
},
// 判断是否全选
isCheckedAll(){
let isAll = false
isAll = this.checkedList.length == this.plainOptions.length ? true : false
this.indeterminate = isAll
this.checkAll = isAll
},
// 确认选中
sumbitOk(){
let extend = this.checkedList.join(',')
this.$emit('isSettingColumnsOk', this.checkedList)
this.$refs.vxePulldown.hidePanel()
this.Downtype = false
},
// 还原全选
sumbitReset(){
this.checkAll = true
let newList = []
this.plainOptions.forEach(item =>{
newList.push(item.dataIndex)
if(item.children && item.children.length>0){
item.children.forEach((itm,u)=>{
newList.push(itm.dataIndex)
if(itm.children&&itm.children.length>0){
itm.children.forEach((imt,ui)=>{
newList.push(imt.dataIndex)
})
}
})
}
})
this.checkedList = newList
let extend = this.checkedList.join(',')
this.$nextTick(() => {
this.$emit('isSettingColumnsOk', this.checkedList)
this.$refs.vxePulldown.hidePanel()
this.Downtype = false
})
},
}
}
style 样式部分修改;
.toolbar-meta{
position: relative;
}
.downBox{
width: 220px;
position: relative;
overflow: hidden;
border: 1px solid #999;
border-radius: 4px;
.checkTopAll{
position: absolute;
top: 0;
left: 0;
border-bottom: 1px solid #999;
padding: 10px 5px;
width:100%;
background-color: #fff;
z-index: 999;
}
.checkItem{
position: relative;
width: 220px;
max-height:200px;
overflow:auto;
padding: 10px;
margin-bottom: 40px;
.checkLi{
display: block;
width: 100%;
}
.ant-checkbox-group-item{
display: block;
}
}
.downBtn{
position: absolute;
z-index: 999;
bottom: 0;
left: 0;
width: 100%;
padding: 5px 10px;
background: #fff;
border-top:1px solid #999;
.btnReset{
float: right;
}
}
}
2、引用组件:setTableToolbar
<set-table-toolbar ref="setTableToolbar1" :columns="defColumns" @isSettingColumnsOk="isSettingColumnsOk" @reshload="reshColumns"></set-table-toolbar>
<script>
// 列配置
import setTableToolbar from "./common/setTableToolbar.vue"
export default {
components: {
setTableToolbar
},
data() {
return {
tableColumnsParams:{},
settingColumns: [],
defColumns: []
}
},
methods:{
// 配置列点击确认
isSettingColumnsOk(settingColumnsStr){
if (settingColumnsStr&&settingColumnsStr.length>0) {
this.settingColumns = settingColumnsStr
let params = {
'id': this.tableColumnsParams.id || '',
'tableId': this.tableColumnsParams.cgformHeadId || this.code,
'conntent': settingColumnsStr.join(',')
}
Vue.ls.set('保存缓存名字', settingColumnsStr.join(','))
// this.saveColumnsHiding(params)
}
},
// 配置列后获取
reshColumns(){
this.$nextTick(() => {
this.loadData(1)
})
},
}
}
</script>
补充,其他设置:初始执行设置被选项,已选项等;
this.$refs.setTableToolbar.resetListLable(this.defColumns, cols, info)
以上内容仅供参考,具体请根据实际情况选用;