a-tree 实现父级节点禁用,通过子级节点勾选状态控制

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)

以上内容仅供参考,具体请根据实际情况选用;