VUE使用element的el-tree封装2

107 阅读1分钟

对element的el-tree组件的封装,需满足:

checkType : 1 或者 undefine  未选中    2 选中   3 半选中
1. 选中A     直上 父级选中
            直下 子级选中
2. 取消A     直上 父级不变
            直下 子级取消
3. 无半选中  

属性:
    props:
    propsConfig:        //  el-tree 配置   
        {
            label: 'menuName',   
            children: 'childrenList'
        }
    datasource: [],
    checkList: [],
    nodekey: '',
    vt: new date().valueOf();

    event:
        onChange:  // 选择事件    []
        
        

代码如下:

<el-tree 
    :data="treeData"
    :node-key="nodekey"
    :expand-on-click-node="false"
    :props="propsConfig"
    >
    <span class="ui-halftree-custom-tree-node" slot-scope="{ node, data }">
        <div :key="data.id" class="check-box" @click.stop.prevent="toggleSelect(data, node)">
            <el-checkbox v-if="data.checkType == 2" checked ></el-checkbox>
            <el-checkbox v-else ></el-checkbox>
            <span class="check-mask"></span>
        </div>

        <span>{{ node.label }}</span>
    </span>
</el-tree>
import { cloneDeep, includes } from 'lodash'

    export default {
        props: {
            propsConfig: {
                type: Object,
                default: () => {}
            },
            nodekey: {
                type: String,
                default: 'id'
            },
            datasource: {
                type: Array,
                default: () => []
            },
            checkList: {
                type: Array,
                default: () => []
            },
            vt: {
                type: Number | String,
                default: 1
            },
        },
        data() {
            return {
                treeData: [],
            };
        },
        watch: {
            vt: {
                handler: function(newVal, oldVal) {
					this.initData();
                },
                immediate: true,
            },
        },
        methods: {
            initData() {
                this.treeData = cloneDeep(this.datasource);
                this.initCheckData();
            },
            initCheckData() {
                if(this.checkList.length > 0) {
                    let childName = this.propsConfig.children || 'children';
                    this.dealCheckData(this.treeData, childName);
                }
            },
            dealCheckData(arr, childName) {
                arr.forEach(i => {
                    if(i && i[this.nodekey] && includes(this.checkList, i[this.nodekey])) {
                        i.checkType = 2;
                    }
                    if(i && i[childName] && i[childName].length > 0) {
                        this.dealCheckData(i[childName], childName)
                    }
                });
            },
            toggleSelect(data, node) {
                data.checkType = 3 - (data.checkType || 1);
                let childName = this.propsConfig.children || 'children';

                if(data.checkType == 2) { // 选中
                    if(data[childName] && data[childName].length > 0) {
                        this.checkChildArr(data[childName], childName);
                    }
                    this.checkParentArr(this.treeData, data[this.nodekey], childName);
                } else { // 未选中
                    this.cancleChildArr(data[childName], childName);
                }
                this.dealCheckArr();

            },
            checkParentArr(list, itemId, childName){
                let res = false;
                let childRes = false;
                list.forEach(i => {
                   
                    if(i && i[this.nodekey]  && i[this.nodekey] == itemId) {
                        res = true;
                    } else {
                        if(i && i[childName] && i[childName].length > 0) {
                            childRes = this.checkParentArr(i[childName], itemId, childName);
                            if(childRes) {
                                res = true;
                                i.checkType = 2;
                            }
                        }
                    }
                });
                return res;
            },
            checkChildArr(list, childName){
                list.forEach(i => {
                    if(i && i[this.nodekey]) {
                        i.checkType = 2;
                    }
                    if(i && i[childName] && i[childName].length > 0) {
                        this.checkChildArr(i[childName], childName);
                    }
                });
            },
            cancleChildArr(list, childName){
                list.forEach(i => {
                    if(i && i[this.nodekey]) {
                        i.checkType = 1;
                    }
                    if(i && i[childName] && i[childName].length > 0) {
                        this.cancleChildArr(i[childName], childName);
                    }
                });
            },
            getCheckKey(arr, childName) {
                let res = [];
                arr.forEach(i => {
                    if(i && i[this.nodekey]) {
                        if(i.checkType == 2) {
                            res.push(i[this.nodekey]);
                        }
                    }
                    if(i && i[childName] && i[childName].length > 0) {
                        res = res.concat(this.getCheckKey(i[childName], childName));
                    }
                });

                return res;
            },
            dealCheckArr() {
                let list = [];
                let arr = cloneDeep(this.treeData);
                let childName = this.propsConfig.children || 'children';
                list = this.getCheckKey(arr, childName);
                this.$emit('onChange', list);
            }
        }
    }
.ui-halftree-custom-tree-node {
    .check-box {
        position: relative;
        display: inline-block;
        margin-right: 0.4rem;
    }
    .check-mask {
        position: absolute;
        display: inline-block;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
        z-index: 5;
    }
}