基于el-select简单封装一个组件

主要的功能有:

                 1.全选

                 2.传入禁用的ID,把对应是数据禁用

子组件

<template>
    <div>
        <el-select
            v-model="selectedArray"
            v-bind="$attrs"
            @change="changeSelect"
            @remove-tag="removeTag"
        >
            <el-option
                v-if="showSelectAll"
                label="全选"
                value="全选"
                @click.native="selectAll"
            />
            <el-option
                v-for="(item, index) in options"
                :key="index"
                :label="item.label"
                :value="item.value"
                :disabled="item.disabled"
            />
        </el-select>
    </div>
</template>

<script>
import { cloneDeep } from '@mcfe/tools';

export default {
    name: 'SelectAll',
    props: {
        // v-model绑定的值
        value: {
            type: [String, Number, Array],
            default: '',
        },
        labelKey: {
            type: [String, Function],
            default: 'label',
        },
        valueKey: {
            type: String,
            default: 'value',
        },
        // 数据源
        source: {
            type: [Array, String],
            default: () => ([]),
        },
        // 是否有全选功能
        showSelectAll: {
            type: Boolean,
            default: false,
        },
        // 禁止的属性
        disabledIds: {
            type: Array,
            default: () => ([]),
        },
    },
    data() {
        return {
            selectedArray: [],
            options: this.source,
            isSelectAll: false, // 添加isSelectAll属性
        };
    },
    watch: {
        disabledIds: {
            deep: true,
            immediate: true,
            handler() {
                this.options = this.disabledList(this.options);
            },
        },
    },
    methods: {
        // 点击全选时
        selectAll() {
            if (this.showSelectAll) {
                // 如果isSelectAll为true,则清空selectedArray,实现取消全选
                if (this.isSelectAll) {
                    this.selectedArray = [];
                    this.isSelectAll = false; // 设置isSelectAll为false
                } else {
                    // 否则,将options中非禁止选择的value添加到selectedArray中,实现全选
                    this.selectedArray = this.options.filter(({ disabled }) => !disabled).map(({ value }) => value);
                    this.selectedArray.unshift('全选');
                    // 设置isSelectAll为true
                    this.isSelectAll = true;
                }
            }
            this.$emit('input', this.selectedArray);
        },
        // 选中的值发生变化
        changeSelect(val) {
            if (this.showSelectAll) {
                if (typeof val === 'number') {
                    console.warn('单选的时候就不要传showSelectAll了.');
                    return;
                }
                // 获取非禁止选择的数据的长度
                const enabledOptionsLength = this.options.filter(({ disabled }) => !disabled).length;
                // 如果选中的值不包括全选且选中值的长度和非禁止选择的数据的长度相等,证明这时候已经全选了,把全选追加到选中的数组中
                if (!val.includes('全选') && val.length === enabledOptionsLength) {
                    this.selectedArray.unshift('全选');
                } else if (val.includes('全选') && (val.length - 1) < enabledOptionsLength) {
                    // 当全选时,删除了一项数据
                    this.selectedArray = this.selectedArray.filter((item) => item !== '全选');
                }
            }
            this.$emit('input', this.selectedArray);
        },

        // 全选的时候, 如果点击删除全选就把选中的数据清空
        removeTag(val) {
            if (this.showSelectAll && val === '全选') {
                this.selectedArray = [];
            }
            this.$emit('input', this.selectedArray);
        },

        // 禁用列表
        disabledList(list = []) {
            const { disabledIds = [], labelKey, valueKey } = this;
            // 使用 cloneDeep 深拷贝列表数据,避免修改原数据
            // 使用 map 方法遍历列表数据,对每一项进行格式化处理
            const stackList = cloneDeep(list).map((item) => {
                const stack = {};
                // 如果 disabledIds 存在,且为数组,且包含当前项的 valueKey,则将当前项的 disabled 属性设为 true
                if (disabledIds && Array.isArray(disabledIds) && disabledIds.includes(item[valueKey])) {
                    stack.disabled = true;
                }
                // 根据 labelKey 的类型,如果是函数则调用函数获取 label,否则直接从 item 中获取 label
                const label = (typeof labelKey === 'function') ? labelKey(item) : item[labelKey];
                // 返回格式化后的当前项,包含 disabled,label,value 属性
                return {
                    ...stack,
                    label,
                    value: item[valueKey],
                };
            });
            // 返回格式化后的列表数据
            return stackList;
        },
    },
};
</script>

父组件

           <my-select
             v-model="poiIdList"
             show-select-all
             collapse-tags
             clearable
             filterable
             :label-key="labelKey"
             multiple
             :disabled-ids="disabledIds"
             :source="PayTypeEnum"
             placeholder="请选择xxxx"
           />

            
            // 要禁用的属性
            disabledIds: [1],
            // 自定义labelKey
            labelKey(item) {
                return `${item.label}[(${item.value})]`;
            },
            // 数据源 
            PayTypeEnum: [
                { label: '1转账', value: 1 },
                { label: '2支票', value: 2 },
                { label: '3转账', value: 3 },
                { label: '4支票', value: 4 },
                { label: '5转账', value: 5 },
                { label: '6支票', value: 6 },
                { label: '7转账', value: 7 },
                { label: '8支票', value: 8 },
                { label: '9转账', value: 9 },
                { label: '10支票', value: 10 },
                { label: '11转账', value: 11 },
            ]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值