Files
xgy-oa/klp-ui/src/components/MutiSelect/index.vue
2026-04-16 15:50:54 +08:00

163 lines
3.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="muti-select">
<!-- 下拉选择模式 -->
<div v-if="type === 'select'" class="select-container">
<el-select
v-model="innerValue"
multiple
:placeholder="placeholder"
:filterable="filterable"
:clearable="clearable"
:allow-create="allowAdd"
:disabled="disabled"
:size="size"
@change="handleChange"
>
<!-- 全选选项 -->
<!-- <el-option
v-if="showSelectAll && options.length > 0"
key="selectAll"
label="全选"
value="selectAll"
@click="toggleSelectAll"
/> -->
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<!-- 复选框模式 -->
<div v-else-if="type === 'checkbox'" class="checkbox-group">
<el-checkbox-group v-model="innerValue" @change="handleCheckboxChange">
<el-checkbox
v-for="item in options"
:key="item.value"
:label="item.value"
:disabled="disabled"
>
{{ item.label }}
</el-checkbox>
</el-checkbox-group>
<el-button
v-if="showSelectAll && options.length > 0"
type="text"
size="small"
@click="toggleSelectAll"
>
{{ isAllSelected ? '取消全选' : '全选' }}
</el-button>
</div>
</div>
</template>
<!-- v-model 绑定逗号分隔的字符串可以 props 配置是否允许新增 -->
<script>
export default {
name: 'MutiSelect',
props: {
value: {
type: String,
default: ''
},
options: {
type: Array,
default: () => []
},
allowAdd: {
type: Boolean,
default: false
},
type: {
type: String,
default: 'select' // select or checkbox
},
placeholder: {
type: String,
default: '请选择'
},
filterable: {
type: Boolean,
default: true
},
clearable: {
type: Boolean,
default: true
},
disabled: {
type: Boolean,
default: false
},
size: {
type: String,
default: 'default' // large, default, small
},
showSelectAll: {
type: Boolean,
default: true
}
},
// 计算属性捕获实现双向绑定
computed: {
innerValue: {
get() {
if (!this.value) {
return [];
}
return this.value?.split(',');
},
set(val) {
const newValue = val?.join(',') ?? '';
this.$emit('input', newValue);
this.$emit('change', newValue);
}
},
// 是否全选
isAllSelected() {
return this.options.length > 0 && this.innerValue.length === this.options.length;
}
},
methods: {
// 处理选择变化
handleChange(val) {
// 过滤掉 'selectAll' 选项
const filteredVal = val.filter(item => item !== 'selectAll');
this.$emit('change', filteredVal.join(','));
},
// 处理复选框变化
handleCheckboxChange(val) {
const newValue = val.join(',');
this.$emit('input', newValue);
this.$emit('change', newValue);
},
// 切换全选/取消全选
toggleSelectAll() {
if (this.isAllSelected) {
this.innerValue = [];
} else {
this.innerValue = this.options.map(item => item.value);
}
}
}
}
</script>
<style scoped>
.muti-select {
width: 100%;
}
.checkbox-group {
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: center;
}
.checkbox-group .el-checkbox {
margin-right: 10px;
}
</style>