因为 element-plus的Virtualized Select 虚拟化选择器(el-select-v2)全选有bug
故封装了普通版el-select 并记录
上图
1.子组件
<el-select v-model="selected" filterable multiple clearable collapse-tags collapse-tags-tooltip :collapse-tags-tooltip-placement="tooltipPlacement" :placeholder="placeholder" :props="props.props" popper-class="custom-header" :max-collapse-tags="maxCollapseTags" style="width: 240px">
<template #header>
<el-checkbox v-model="isAllChecked" :indeterminate="isIndeterminate" @change="handleCheckAll">全选</el-checkbox>
</template>
<el-option v-for="item in options" :key="item.id" :label="item.title" :value="item.id" />
</el-select>
js部分:
<script setup lang="ts">
import { ref, watch, onMounted } from 'vue';
import type { CheckboxValueType } from 'element-plus';
// 定义组件接收的属性
const props = defineProps({
value: {
type: Array,
default: () => [],
},
options: {
default() {
return []
},
type: Array as () => Array<{ id: number, title: string }>,
},
placeholder: {
type: String,
default: '请选择',
},
maxCollapseTags: {
type: Number,
default: 3,
},
tooltipPlacement: {
type: String,
default: 'top',
},
props: {
type: Object,
default: () => ({
label: 'title',
value: 'id',
}),
},
});
onMounted(()=>{
updateCheckAllStatus()
})
// 定义组件发出的事件
const emit = defineEmits(['update:value']);
// 定义组件内部状态
const selected = ref<any>(props.value);
const isAllChecked = ref(false);
const isIndeterminate = ref(false);
// 监听 value 的变化
watch(
() => props.value,
(newVal) => {
selected.value = newVal;
console.log(selected.value);
updateCheckAllStatus();
},
);
// 处理全选逻辑
const handleCheckAll = (val: CheckboxValueType) => {
if (isAllChecked.value) {
selected.value = props.options.map((option: any) => option.id);
} else {
selected.value = [];
}
emit('update:value', selected.value);
};
// 更新全选状态
const updateCheckAllStatus = () => {
if (selected.value.length === props.options.length) {
isAllChecked.value = true;
isIndeterminate.value = false;
} else if (selected.value.length > 0) {
isAllChecked.value = false;
isIndeterminate.value = true;
} else {
isAllChecked.value = false;
isIndeterminate.value = false;
}
};
// 监听 selected 的变化,同步给父组件
watch(selected, (newVal) => {
emit('update:value', newVal);
updateCheckAllStatus();
});
</script>
2.父组件:
<ElSelectV1 class="ml-1" :value="selectedValues" :options="options" :params="params" @update:value="handleValueUpdate" :placeholder="'请选择任务'"></ElSelectV1>
js部分:
<script setup lang="ts">
import ElSelectV1 from '@/components/Selector/index.vue';
const selectedValues = ref<any>();
const options = ref<any>([]);
let params = reactive<any>({});
// 处理子组件发出的更新事件
function handleValueUpdate(newValues: string[]) {
selectedValues.value = newValues;
}
selectedValues:选择器已选中内容的id
options:选择器中所有的内容 (lable:展示名字,id:。。。)子组件中可修改
placeholder:输入框中的提示语。 默认为‘请选择’
handleValueUpdate:子组件更新后的回调函数