创建组件
- 在 components 目录下创建组件 MultipleSelect.vue
- 组件代码
<template>
<div style="display: flex">
<el-select
style="width: 300px"
size="mini"
multiple
filterable
:disabled="disabled"
v-model='selectedArr'
:loading="mulSelectLoading"
:collapse-tags="collapseTags"
placeholder='请选择'
@change='changeSelect'
@remove-tag='removeTag'>
<el-option label='全选' value='全选' @click.native='selectAll' v-if="selectOptions.length"></el-option>
<el-option v-for='item in selectOptions' :key='item.value' :label='item.label' :value='item.value'></el-option>
</el-select>
</div>
</template>
<script>
export default {
name: 'MultipleSelect',
data () {
return {
selectedArr: []
}
},
props: {
// 选项
selectOptions: {
type: Array,
default () {
return []
}
},
// 是否禁用
disabled: {
type: Boolean,
default: false
},
// 已选中选项
mulSelecteds: {
type: Array,
default () {
return []
}
},
mulSelectLoading: {
type: Boolean,
default: false
},
collapseTags: {
type: Boolean,
default: true
}
},
methods: {
selectAll () {
if (this.selectedArr.length < this.selectOptions.length) {
this.selectedArr = []
this.selectOptions.map((item) => {
this.selectedArr.push(item.value)
})
this.selectedArr.unshift('全选')
} else { // 取消全选
this.selectedArr = []
}
this.$emit('update:updateMultipleSelect', this.selectedArr)
},
changeSelect (val) {
if (!val.includes('全选') && val.length === this.selectOptions.length) {
this.selectedArr.unshift('全选')
} else if (val.includes('全选') && (val.length - 1) < this.selectOptions.length) {
this.selectedArr = this.selectedArr.filter((item) => {
return item !== '全选'
})
}
this.$emit('update:updateMultipleSelect', this.selectedArr)
},
removeTag (val) {
if (val === '全选') {
this.selectedArr = []
this.$emit('update:updateMultipleSelect', this.selectedArr)
}
}
},
watch: {
mulSelecteds: {
handler (newVal, oldVal) {
this.selectedArr = newVal
if (!this.selectedArr.includes('全选') &&
this.selectedArr.length &&
this.selectedArr.length === this.selectOptions.length) {
this.selectedArr.unshift('全选')
}
},
immediate: true
}
}
}
</script>
- 父组件中引用
<template>
<div class="app">
<el-card class="box-card">
<MultipleSelect
:selectOptions="selectOptions"
:mulSelectLoading="mulSelectLoading"
:mulSelecteds="mulSelecteds"
@update:updateMultipleSelect="val => mulSelecteds = val">
</MultipleSelect>
</el-card>
</div>
</template>
<script>
import MultipleSelect from './components/MultipleSelect'
export default {
data () {
return {
selectOptions: [],
mulSelectLoading: false,
mulSelecteds: []
}
},
components: {
MultipleSelect
},
methods: {
mockData () {
this.mulSelectLoading = true
setTimeout(() => {
const options = [
{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'}
]
this.selectOptions = options
this.mulSelectLoading = false
this.mulSelecteds = ['2', '4']
}, 1500)
}
},
mounted () {
this.mockData()
}
}
</script>
<style>
.text {
font-size: 14px;
}
.item {
padding: 18px 0;
}
.box-card {
max-height: 400px;
line-height: 20px;
}
</style>