根据el-select和el-checkbox构建前面带框的多选下拉组件
html代码
<div class="name-mult-select">
<el-select class="af_r_right" :class="classSelectName" :ref="refSelectName" value-key="id" v-model="staffName"
multiple clearable placeholder="可选择" @clear="clearStaffName" @visible-change="openStaffSelect" @change="changeMulSelect"
:popper-class="staffNameList.length > 0 ? submitBtn ? 'btn-class' : '' : 'no-detail'">
<div style="padding:6px 16px 6px 16px;" v-if="isopenFilter">
<el-input v-model="inputStaffName" clearable placeholder="关键词搜索"></el-input>
</div>
<el-option label='全部' value='全部' v-if="!inputStaffName && staffNameList.length > 0">
<el-checkbox style="width: 100%;" label="全部" v-model="isAllStaffName" @change="selectAll">全部</el-checkbox>
</el-option>
<el-option v-for="item in staffNameList" :key="item[settingId]" :label="item[settingName] || item[elseName]" :value="item[settingId]">
<el-checkbox style="width: 100%;" :label="item[settingName] || item[elseName]" v-model="item.isSelect" @change="changeStaffName(item)">{{item[settingName] || item[elseName]}}
</el-checkbox>
</el-option>
<div class="btn" v-if="submitBtn">
<el-button style="margin-left:10px;" type="primary" plain @click="cancelSelectStaff">取消
</el-button>
<el-button type="primary" @click="selectStaff">确认</el-button>
</div>
</el-select>
</div>
js代码
return Vue.extend({
props: {
allSelectList: {
type: Array
},
selectInitData: {
type: Array
},
selectSetting: {
type: Object
},
allSelectFunction: {
type: Function,
}
},
data: function () {
return {
allStaffNameList: [],//全部数组,不会受到逻辑影响
staffNameList: [],//处理后需要显示的数组
inputStaffName: null,
isAllStaffName: false,
staffId: [],//当前的id
staffName: [],//储存文字,展示在多选框上
allStaff: [],
// 一些特殊的设置
submitBtn: false,
isopenFilter: true,
refSelectName: 'staffSelect',
classSelectName: 'staffName',
settingId: 'value',
settingName: 'label',
elseName: 'label'
}
},
created() {
},
mounted() {
this.allStaffNameList = util.deepClone(this.allSelectList);
this.staffNameList = util.deepClone(this.allSelectList);
this.staffId = util.deepClone(this.selectInitData);
// 特殊设置
this.submitBtn = this.selectSetting && this.selectSetting.isOpenSubmitBtn ? true : false;
this.isopenFilter = this.selectSetting && this.selectSetting.isopenFilter ? this.selectSetting.isopenFilter : true;
this.refSelectName = this.selectSetting && this.selectSetting.refName ? this.selectSetting.refName : 'staffSelect';
this.classSelectName = this.selectSetting && this.selectSetting.selectName ? this.selectSetting.selectName : 'staffName';
this.settingId = this.selectSetting && this.selectSetting.id ? this.selectSetting.id : 'value';
this.settingName = this.selectSetting && this.selectSetting.name ? this.selectSetting.name : 'label';
this.elseName = this.selectSetting && this.selectSetting.elseName ? this.selectSetting.elseName : 'label'
// 获取全部的id
this.allStaffNameList.forEach((item) => {
item.isSelect = false;
this.allStaff.push(item[this.settingId]);
})
this.allStaff = Array.from(new Set(this.allStaff))
},
destroyed() {
},
watch: {
allSelectList: {
handler(newV, oldV) {
this.allStaffNameList = util.deepClone(this.allSelectList);
this.staffNameList = util.deepClone(this.allSelectList);
// 获取全部的id
this.allStaffNameList.forEach((item) => {
item.isSelect = false;
this.allStaff.push(item[this.settingId]);
})
this.allStaff = Array.from(new Set(this.allStaff))
},
immediate: true
},
// 重置属性
selectInitData: {
handler(newV, oldV) {
const checkFn = function (a, b) {
let same = false;
if (a && b) {
same = JSON.stringify(a) === JSON.stringify(b);
}
return same
};
if (checkFn(newV, oldV)) return;
this.staffId = util.deepClone(this.selectInitData);
},
immediate: true
},
'staffId': function (newVal, oldval) {
if (newVal) {
this.isAllStaffName = false;
this.handelStaffName(newVal);
}
},
// 接待客服组件搜索
inputStaffName(val) {
var re = /^[a-zA-Z]{1}/;
var staffList = util.deepClone(this.allStaffNameList);
// 搜索重置属性
staffList.forEach((item) => {
item.isSelect = false;
})
if (this.staffId.length > 0) {
for (var i = 0; i < this.staffId.length; i++) {
staffList.forEach((item) => {
if (item[this.settingId] == this.staffId[i]) {
item.isSelect = true;
}
})
}
}
if (val) {
var newOption = staffList.filter((i) => {
return i[this.settingName].indexOf(val) != -1;
})
if (newOption && newOption.length > 0) {
this.staffNameList = newOption;
} else {
this.staffNameList = [];
}
} else {
this.staffNameList = staffList;
}
},
},
methods: {
//选择全部按钮进行的操作
selectAll(val) {
this.isAllStaffName = val;
if (val) {
// 全选
this.staffId = util.deepClone(this.allStaff);
this.staffNameList.forEach((item, index) => {
item.isSelect = true;
});
} else {
this.staffId = [];
this.staffNameList.forEach((item, index) => {
item.isSelect = false;
});
}
this.handelStaffName(this.staffId)
},
// 改变接待客服判断是否全选
changeStaffName(val) {
// 选择单个客服
if (this.staffId.indexOf(val[this.settingId]) == -1) {
this.staffId.push(val[this.settingId])
} else {
this.staffId.splice(this.staffId.indexOf(val[this.settingId]), 1)
}
if (!this.isAllStaffName && this.staffId.length === this.allStaff.length) {
this.isAllStaffName = true;
} else if (this.isAllStaffName && (this.staffId.length < this.allStaff.length)) {
this.isAllStaffName = false;
}
this.handelStaffName(this.staffId)
},
// 当点击空白处时不允许选中
changeMulSelect(val){
if(!this.staffNameTxt){
this.staffName = []
}
},
//点击清除按钮时触发的操作
clearStaffName() {
this.staffId = [];
this.inputStaffName = null;
this.staffName = [];
this.isAllStaffName = false;
this.allStaffNameList.forEach((item, index) => {
item.isSelect = false;
});
this.staffNameList = this.allStaffNameList;
this.handelStaffName(this.staffId);
this.$emit('submitSelect', this.staffId, this.staffNameTxt)
},
// 处理选中客服的样式
handelStaffName(newVal) {
// 判断是否全选
var arr = [];
var staffNameTxt = '';
if (newVal.indexOf('全部') != -1 || this.isAllStaffName || (newVal.length === this.allStaff.length && this.allStaff.length != 0)) {
this.isAllStaffName = true;
// 处理客服每次打开的选中
if (newVal.length > 0) {
this.staffNameList.forEach((item, index) => {
if (newVal.indexOf(item[this.settingId]) != -1 || newVal.indexOf(String(item[this.settingId])) != -1) {
item.isSelect = true;
}
});
}
staffNameTxt = '全部';
} else {
this.allStaffNameList.forEach((item, index) => {
for (var j = 0; j < newVal.length; j++) {
if (item[this.settingId] == newVal[j]) {
arr.push(item[this.settingName] ? item[this.settingName] : item[this.elseName])
}
}
});
// 处理客服每次打开的选中
this.staffNameList.forEach((item, index) => {
if (newVal.indexOf(item[this.settingId]) != -1 || newVal.indexOf(String(item[this.settingId])) != -1) {
item.isSelect = true;
}
});
for (var i = 0; i < arr.length; i++) {
staffNameTxt += arr[i] + '、';
}
staffNameTxt = staffNameTxt.substring(0, staffNameTxt.length - 1);
}
this.staffNameTxt = staffNameTxt;
this.staffName = staffNameTxt ? [staffNameTxt] : [];//用作标识有内容
this.$emit('allSelectFunction', newVal, staffNameTxt)//将id和文字传给父级
this.$nextTick(() => {
$('.' + this.classSelectName + ' .el-select__tags').text(staffNameTxt)
$('.' + this.classSelectName + ' .el-select__tags').attr("title", staffNameTxt)
})
},
//打开下拉框时需要重新渲染数据
openStaffSelect(val) {
if (val) {
this.inputStaffName = null;
if (this.staffId && this.staffId.length == 0) {
this.inputStaffName = null;
this.staffName = [];
this.isAllStaffName = false;
this.staffNameTxt = ''
this.staffNameList.forEach((item, index) => {
item.isSelect = false;
});
}
}
},
// 取消按钮
cancelSelectStaff() {
this.$refs[this.refSelectName].blur();
this.inputStaffName = null;
this.isAllStaffName = false;
this.staffName = [];
this.staffId = [];
this.staffNameTxt = '';
this.staffNameList.forEach((item, index) => {
item.isSelect = false;
});
this.$emit('cancelSelect', this.staffId, this.staffNameTxt)
},
// 确定选择
selectStaff() {
this.$refs[this.refSelectName].blur();
this.$emit('submitSelect', this.staffId, this.staffNameTxt)
},
},
template: template,
})
css代码
.name-mult-select{
display: inline-block;
.no-detail {
.el-scrollbar {
display: block !important;
}
.btn {
display: none;
position: absolute;
width: 100%;
bottom: 0;
border-top: 1px solid #e5e5e5;
}
}
.btn-class {
.el-scrollbar {
display: block !important;
}
.el-scrollbar {
padding-bottom: 50px;
}
.is-vertical {
padding-bottom: 50px;
}
.btn {
position: absolute;
width: 100%;
bottom: 0;
border-top: 1px solid #e5e5e5;
}
}
}
使用方法
* <kf-all-select :allSelectList="allSelectList" :selectInitData="array" @allSelectFunction="allSelectFunction" :selectSetting="selectSetting"></kf-all-select>
*
* allSelectList:整体数据结构
* selectInitData:选中的值,没有就传[],
* allSelectFunction:选中时传给父的回调函数
* selectSetting:一些特殊的设置
* selectSetting:{
* id:'value',
* name:'label',//设置读取的字段名
* elseName:'elseName',//当name这个值获取在接口需要用其他值替换时传
* isopenFilter:false,//开启模糊搜索
* isOpenSubmitBtn:false,//是否开启按钮,放在页面的搜索框一般设为true
* refName:'staffSelect',//设置不同的ref,避免有多个时互相影响样式,默认是staffSelect
* selectName:'staffName',//设置类名,用于多个选框会出现文案影响,默认是staffName
* }