实现效果
组件使用
使用v-model ,v-model为已选择的列表,list为全量列表
<select-all
:list="moduleList"
v-model="formData.buildModuleIds"
width="600px"
></select-all>
二次封装el-select组件
<template>
<div :style="{ width }" class="select-all">
<el-select
multiple
v-model="selectedList"
@change="changeSelect"
@remove-tag="removeTag"
placeholder="请选择"
class="select-list"
v-bind="$attrs"
>
<el-option
v-if="list.length"
:label="`全选(${selectCountText})`"
value="全选"
@click.native="selectAll"
></el-option>
<el-option
v-for="item in list"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
<span class="select-count" v-if="showCount && selectedList.length">
{
{
selectCountText }}
</span>
</div>
</template>
<script>
import {
cloneDeep } from 'lodash-es';
export default {
model: {
prop: 'selects',
event: 'changList'
},
props: {
selects: {
type: Array,
default: () => []
},
list: {
type: Array,
default: () => []
},
width: {
type: String,
default: '200px'
},
showCount: {
type: Boolean,
default: true
}
},
data() {
return {
selectedList: cloneDeep(this.selects)
};
},
computed: {
selectCountText() {
let length = this.selectedList.length;
if (this.selectedList.includes('全选')) length = length - 1;
return `${
length}/${
this.list.length}`;
}
},
watch: {
selects: {
handler(nv) {
if (nv.length && nv.length === this.list.length) {
if (!this.selectedList.includes('全选'))
this.selectedList.unshift('全选');
}
},
deep: true,
immediate: true
},
list: {
handler(nv) {
if (nv.length && nv.length === this.selects.length) {
if (!this.selectedList.includes('全选'))
this.selectedList.unshift('全选');
}
},
immediate: true,
deep: true
}
},
methods: {
selectAll() {
if (this.selectedList.length < this.list.length) {
this.selectedList = [];
this.list.map(item => {
this.selectedList.push(item.value);
});
this.selectedList.unshift('全选');
} else {
this.selectedList = [];
}
this.emitChange();
},
changeSelect(val) {
if (!val.includes('全选') && val.length === this.list.length) {
this.selectedList.unshift('全选');
} else if (val.includes('全选') && val.length - 1 < this.list.length) {
this.selectedList = this.selectedList.filter(item => item !== '全选');
}
this.emitChange();
},
removeTag(val) {
if (val === '全选') this.selectedList = []
this.emitChange();
},
emitChange() {
const selectedList = this.selectedList.filter(item => item !== '全选');
this.$emit('changList', selectedList);
}
}
};
</script>
<style lang="scss" scoped>
.select-all {
position: relative;
.select-list {
width: 100%;
}
.select-count {
display: inline-block;
line-height: 20px;
text-align: right;
position: absolute;
bottom: 0;
right: 2px;
color: #909399;
font-size: 12px;
}
}
</style>
本文参考https://segmentfault.com/a/1190000019945631,并进行二次封装