二级多选el-check 组件 vue2

<template>
    <div class="TestCheck">
        <div class="p-content fr">
            <el-checkbox class="pItme fr_c" :value="pAllCheck" @change="onChangePAll" :indeterminate="pAllIndeterminate"
                >全部</el-checkbox
            >
            <div
                class="pItme fr_c"
                v-for="(pItem, index) in list"
                :key="index"
                :class="{ actived: border && sPItem.name == pItem.name }"
            >
                <el-checkbox
                    v-model="pItem.check"
                    @change="onChangePItem(pItem)"
                    :indeterminate="pIndeterminate(pItem)"
                >
                    {{ pItem.name }}
                </el-checkbox>
                <div class="module cp" v-show="border" @click="sPItem = pItem"></div>
            </div>
        </div>
        <div class="c-content fr" v-show="sPItem.child">
            <el-checkbox class="cItme fr_c" :value="cAllCheck" @change="onChangeCAll" :indeterminate="cAllIndeterminate"
                >全部</el-checkbox
            >
            <div class="cItme fr_c" v-for="(cItem, index) in sPItem.child" :key="index">
                <el-checkbox v-model="cItem.check" @change="onChangeCItem">{{ cItem.name }}</el-checkbox>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    name: "TestCheck",
    props: {
        list: {
            type: Array,
            default: () => {
                return [
                    {
                        name: "未新建/关联商讯",
                        check: false,
                        child: [
                            { name: "未读取", key: 0, check: false },
                            { name: "仅读取", key: 1, check: false },
                            { name: "已读取-接受", key: 2, check: false },
                            { name: "已读取-拒绝", key: 5, check: false },
                        ],
                    },
                    {
                        name: "已新建/关联商讯",
                        check: false,
                        child: [
                            { name: "已新建销售机会", key: 3, check: false },
                            { name: "已关联销售机会", key: 4, check: false },
                        ],
                    },
                    {
                        name: "已审核移除商讯",
                        check: false,
                        child: [{ name: "已移除", key: 6, check: false }],
                    },
                ];
            },
        },
        //是否要点击切换
        border: {
            type: Boolean,
            default: true,
        },
    },
    data() {
        return {
            sPItem: {},
        };
    },
    computed: {
        //父级全选的半选
        pAllIndeterminate() {
            let havCheckArr = this.list.filter((pItem) => {
                return pItem.child?.some((cItem) => {
                    return cItem.check;
                });
            });
            return !this.pAllCheck && havCheckArr.length > 0;
        },
        //子级全选的半选
        cAllIndeterminate() {
            return !this.cAllCheck && this.sPItem?.child?.some((cItem) => cItem.check);
        },
        pAllCheck() {
            return this.list.every((pItem) => pItem.check);
        },
        cAllCheck() {
            return this.sPItem?.child?.every((cItem) => cItem.check);
        },
    },
    methods: {
        // 对应的父级下存在子级选中的半选
        pIndeterminate(pItem) {
            let pItemHavCheck = pItem.child?.some((cItem) => cItem.check);
            let pAllCheck = pItem.child.every((cItem) => cItem.check);
            return pItemHavCheck && !pAllCheck;
        },
        //父级全选
        onChangePAll() {
            this.sPItem = {};
            let sPAllCheck = !this.pAllCheck;
            this.list.forEach((pItem) => {
                pItem.check = sPAllCheck;
                if (pItem.child) {
                    pItem.child.forEach((cItem) => {
                        cItem.check = sPAllCheck;
                    });
                }
            });
            this.emitData();
        },
        //子级全选
        onChangeCAll() {
            let sCAllCheck = !this.cAllCheck;
            this.sPItem.child.forEach((cItem) => (cItem.check = sCAllCheck));
            this.sPItem.check = this.sPItem.child.every((cItem) => cItem.check);
            this.emitData();
        },
        //点击父级
        onChangePItem(pItem) {
            this.sPItem = pItem;
            this.sPItem.child.forEach((cItem) => (cItem.check = this.sPItem.check));
            this.emitData();
        },
        //点击子级
        onChangeCItem() {
            this.sPItem.check = this.sPItem.child.every((cItem) => cItem.check);
            this.emitData();
        },
        emitData() {
            let arr = [];
            this.list.forEach((pItem) => {
                return pItem.child?.forEach((cItem) => {
                    if (cItem.check) {
                        arr.push(cItem.key);
                    }
                });
            });
            console.log(arr.join(",") || "", "arr");
        },
        //回显选中
        eachoCheck(data = "1,3,5") {
            this.list.forEach((pItem) => {
                pItem.child?.forEach((cItem) => {
                    if (data.includes(cItem.key)) {
                        cItem.check = true;
                    } else {
                        cItem.check = false;
                    }
                });
            });
        },
    },
    mounted() {
        this.sPItem = this.list && this.list[0];
        this.eachoCheck();
    },
};
</script>

<style lang="less" scoped>
.TestCheck {
    margin: 30px;
    .p-content {
        .pItme {
            padding: 0 3px;
            margin-right: 30px;
            position: relative;
            border: 1px solid white;
            &.actived {
                border: 1px solid green;
            }
            .module {
                position: absolute;
                top: 0;
                bottom: 0;
                right: 0;
                left: 16px;
            }
        }
    }
    .c-content {
        margin-top: 10px;
        .cItme {
            padding: 0 3px;
            border: 1px solid white;
            margin-right: 30px;
        }
    }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值