1、组件封装
<template>
<el-select v-model="selectValue" multiple :disabled="disabled" :filterable="false" :collapse-tags="collapseTags" v-bind="$attrs" @change="handleChange" @visible-change="handleChangeVisible" :style="{ width:$attrs.width }">
<div class="select-input">
<el-input v-model="filterValue" placeholder="关键词"></el-input>
</div>
<div class="select-dropdown">
<li class="el-select-dropdown__item no-mark" @click="handleAll" :class="isAll ? 'selected' : ''">
<span class="the-checkbox"></span>
<span>全选</span>
<span class="reverse" @click.stop="handleReverseAll">反选</span>
</li>
</div>
<div class="select-dropdown">
<el-scrollbar wrap-class="scrollbar-wrapper" style="width: calc(100% - 10px)">
<el-option v-for="(item, index) in filterData" :key="index" :label="item[props.label]" :value="item[props.value]" :disabled="disabledFun(item)">
<slot :row="item">
<span class="the-checkbox"></span>
<span>{{ item[props.label] }}</span>
</slot>
</el-option>
<el-option hidden label="" value=""></el-option>
</el-scrollbar>
</div>
</el-select>
</template>
<script>
export default {
name: 'FilterSelectMultiple',
props: {
value: { type: [String, Number, Array], default: (value) => null },
selectData: { type: Array, default: () => [] },
props: {
type: Object,
default: () => { return { value: 'value', label: 'label' } }
},
collapseTags: { type: Boolean, default: true },
showNotSet: { type: Boolean, default: false },
labelText: { type: String, default: '' },
disabled: { type: Boolean, default: false },
disabledFun: { type: Function, default: () => false }
},
data() {
return {
filterValue: '',
selectValue: []
}
},
watch: {
value: {
handler(val) {
this.selectValue = val ?? []
},
immediate: true
}
},
computed: {
filterData() {
return this.selectData && this.selectData.filter((item) => item[this.props.label].indexOf(this.filterValue) > -1)
},
isAll() {
if (this.selectValue.length) {
if (this.filterValue.length) {
const filterItem = this.filterData.filter((item) => this.selectValue.includes(item[this.props.value]))
return filterItem.length === this.selectValue.length
} else {
return this.filterData.length === this.selectValue.length
}
} else {
return false
}
}
},
methods: {
handleAll() {
if (this.isAll) {
this.selectValue = []
} else {
const data = []
this.filterData.forEach((item) => data.push(item[this.props.value]))
this.selectValue = data
}
this.handleChange(this.selectValue)
},
handleReverseAll() {
if (this.isAll) {
this.selectValue = []
} else {
const data = []
this.filterData.forEach((item) => {
if (!this.selectValue.includes(item[this.props.value])) {
data.push(item[this.props.value])
}
})
this.selectValue = data
}
this.handleChange(this.selectValue)
},
handleChange(value) {
let item
if ('multiple' in this.$attrs) {
item = this.selectData.filter((k) => value.includes(k[this.props.value])) || []
} else {
item = this.selectData.find((k) => k[this.props.value] === value) || {}
}
this.$emit('input', value)
this.$emit('change', item)
},
handleChangeVisible() {
this.filterValue = ''
}
}
}
</script>
<style lang="scss" scoped>
.select-input {
padding: 5px 8px 5px 5px;
}
.no-mark {
list-style: none;
}
.select-dropdown {
.el-select-dropdown__item {
.the-checkbox {
display: inline-block;
position: relative;
top: 3px;
border: 1px solid #dcdfe6;
border-radius: 2px;
box-sizing: border-box;
width: 16px;
height: 16px;
background-color: #fff;
z-index: 1;
margin-right: 5px;
}
&.selected {
&::after {
display: none;
}
.the-checkbox {
background-color: #07f;
border-color: #07f;
&:after {
position: absolute;
top: -9px;
left: 1px;
font-family: element-icons;
content: '\e6da';
font-size: 12px;
font-weight: 700;
-webkit-font-smoothing: antialiased;
color: #fff;
}
}
}
}
}
.reverse{
margin-left: 50px;
font-weight: normal;
color: #606266 !important;
}
/deep/.scrollbar-wrapper {
max-height: 168px !important;
}
/deep/.el-select__tags{
overflow: hidden;
}
</style>
2.使用
<FilterSelectMultiple
multiple
v-model="id"
placeholder="请输入xxx"
:selectData="nameList"
:props="{ value: 'id', label: 'name' }"
clearable
class="logicSelect"
@change="handleWarehouseChange"
></FilterSelectMultiple>