elementUI的el-select下拉框多选基础上,自定义下拉框内容,实现品类分组、全选、搜索功能。
先看看效果图
实现的功能:
1.品类分两级,勾选一级品类,实现二级品类全选和反选;
2.全部品类全选和反选;
3.清空已选品类;
4.搜索品类;
HTML部分:
<template>
<el-select
multiple
collapse-tags
v-model="selectNameArr"
placeholder="请选择"
clearable
style="width:280px"
@change="changeSelectBrand"
@remove-tag="removeTag"
@visible-change="initData"
popper-class="select-multiple"
>
<div class="select-box">
<el-form :inline="true" class="select-header">
<el-form-item label="品类选择">
<el-input
size="mini"
v-model="searchValue"
placeholder="请输入关键词"
clearable
@input="searchCat"
></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click.native="selectAll">全选</el-button>
<el-button type="warning" size="mini" @click.native="clearAll">清空</el-button>
</el-form-item>
</el-form>
<div class="select-content" v-if="!loading">
<div class="select-item" v-for="(item,index) in catNameOpt" :key="index">
<div style="margin: 15px 0;font-weight: bold;">
<el-checkbox v-model="item.checked" @change.native="selectAllCat(item,index)">{{item.label}}</el-checkbox>
</div>
<el-option v-for="(subItem,index) in item.children" :key="index" :label="subItem" :value="subItem">
</el-option>
</div>
</div>
<div class="select-content" v-else>
<el-option disabled value="暂无数据" label="暂无数据"></el-option>
</div>
</div>
</el-select>
</template>
JS部分:
export default {
data() {
return {
searchValue: '',
selectNameArr: [],
catNameOpt: [],
catList: [],
loading: false
}
},
methods: {
initData(val) {
// 当下拉框显示的时候请求接口
if(!val) {
return
}
this.getCatMod(this.searchValue ? this.searchValue : '')
},
// 获取品类数据
getCatMod(val) {
let params = {
model: val ? val : ''
}
this.$api.post('/opinion/getCatMod ',params ,res=>{
if(res.code=='00'){
let data = res.returnObject
this.catNameOpt = data
if (data.length === 0) {
// 搜索不到数据时,给个默认选项,不让下拉框收回去
// console.log(111)
this.loading = true
this.catNameOpt = this.catList
return
}
this.loading = false
let newArr = this.catNameOpt.map((item, index) => {
item = {
value: item.category,
label: item.category,
children: item.model,
checked: false
}
return item
});
this.catNameOpt = newArr
if (this.catList.length === 0) {
this.catList = newArr
}
// console.log('this.catNameOpt',this.catList)
}
},err=>{
})
},
dataChange() {
this.$emit('change', this.selectNameArr)
},
// 全选单个品类
selectSingleCat(item) {
let newArr = []
if (item.checked) { // 全选
// console.log('item.checked',item.checked)
this.catNameOpt.map((subItem) => {
if (subItem.value === item.value) {
newArr = subItem.children
}
})
} else {// 反选
let length = item.children.length;
let start = item.children[0];
let index = this.selectNameArr.indexOf(start)
this.selectNameArr.splice(index, length)
// console.log(start, index, length)
// console.log('this.selectNameArr',this.selectNameArr)
}
return newArr
},
// 全选多个品类
selectAllCat(item) {
let singleCatArr = this.selectSingleCat(item);
// console.log('singleCatArr',singleCatArr)
let newArr = this.selectNameArr.concat(singleCatArr)
this.selectNameArr = Array.from(new Set(newArr)) // 数组去重
// console.log('selectNameArr', this.selectNameArr)
this.dataChange()
},
// 全选全部品类
selectAll() {
if (this.selectNameArr.length == 0) {
// 改变checkbox的状态
this.catNameOpt = this.catNameOpt.map((item) => {
let newItem = {
value: item.value,
label: item.label,
children: item.children,
checked: true
}
// console.log('newItem',newItem)
this.selectAllCat(newItem)
return newItem
})
}
},
// 选择品类
changeSelectBrand(val) {
if ((val.length - 1) < this.catNameOpt.length) {
this.selectNameArr = this.selectNameArr.filter((item) => {
return item
})
}
this.dataChange()
// console.log('this.selectNameArr',this.selectNameArr)
},
removeTag(val) {
this.clearAll()
},
// 清空品类
clearAll() {
this.selectNameArr = []
// 改变checkbox的状态
this.catNameOpt = this.catNameOpt.map((item) => {
item.checked = false
return item
});
this.dataChange()
// console.log('selectNameArr', this.selectNameArr)
},
// 搜索品类
searchCat(query) {
if (query !== '') {
this.loading = true;
setTimeout(() => {
this.loading = false;
this.getCatMod(query)
}, 200);
} else {
this.loading = false;
this.catNameOpt = this.catList
}
// console.log('this.catList',this.catList)
this.dataChange()
}
}
}
css部分:
.select-multiple {
.select-box {
padding: 10px;
.select-item {
border-bottom: 1px solid #ccc;
&:last-child{
border: none;
}
}
.select-header {
border-bottom: 1px solid #ccc;
}
.select-content {
height: 210px;
overflow: hidden;
overflow-y: auto;
}
.el-select-dropdown__item {
width: 30%;
display: inline-block;
}
.el-checkbox {
width: 100%
}
}
}