
vue2里的el-select实现全选/取消全选/反选功能

项目场景:
el-select组件拥有优秀的单选,多选功能,这在大部分业务中都能满足我们的需要,但是有这么一种场景却没法满足:’数据太多,我想一键全选怎么做?我想反选怎么做?如何取消全选?
解决方案
答案当然是可以的,我们可以在原有基础上,构建一个符合我们业务需要的el-select组件。一般的option列表都是后端返回的,我们可以与后端相约好,多加一条 ’全选‘来辅助实现,但老师告诉我们,凡事还是靠自己比较好,我们拿到后端返回的数据列表后,我们往里面追加一条 ’全选‘数据,比如像下面:
axios.get(url).then(res => {
if(res.data.code === 200){
this.options= res.data.hospitalList
const all_checked = {
hospital_id:'all',
hospital_name:'全部医院',
}
//追加到第一个位置上
this.options.unshift(all_checked)
}
})
渲染后的效果如下:

文字描述过多可以直接看下面代码。接下来我们需要进行全选/取消全选/反选操作,如果要全选,我们得知道用户是否点击了 全选医院 ,可以通过当前选中数组里是否包含 all,并且记录上一次选中的数组中不能包含 all来判断是否全选,反之就是取消全选。 因为el-select多选的时候,是不知道你此时具体选中了哪个,它返回的是一个数组,用数组最后一位来判断是否选中哪个,只适用用选中的时候,反选就不行,所以我们可以通过当前最新选中的数组,和记录上次选中的数组进行比较,遍历当前最新数组每一个,然后判断上次的数组是否存在这个数据,如果没有存在说明是当前操作的数据,并把结果返回给v-model绑定的数据就实现了反选。 最后一个操作就是 一个一个选中,如果选中完默认就是全选,可以先把 我们一开始push进去的all先取出来,然后进行比较长度,相等就是全选。
changeHospital(val) {
// 判断是否 全选
// 如果当前选中的数组没有 all , 上一个记录的数组有 all,说明是取消全选操作,反之全选
if(this.preList.includes('all') && !latestList.includes('all')){
//取消全选
console.log('cancel checked');
this.curList = [this.options[1].hospital_id] //取消全选 清空数据,默认勾选第一个数据
}else if(!this.preList.includes('all') && latestList.includes('all')){
//全选
console.log('checked all');
this.curList = this.options.map(item => item.hospital_id) //选中全部id
}else{
//说明当前是全选状态,用户点击某条数据,需要进行反选
if(latestList.includes('all')){
//反选
console.log('reverse checked');
//获取这条数据
this.curList = [this.getCurCheckedTarget(this.preList,latestList)]
this.preList = this.curList //反选都是一个 直接赋值就行
return
}
// 判断前,需要先把 all 删除
let temp = [...this.options]
temp.splice(0,1)
if(latestList.length === temp.length){ //单个全勾选后,就是全选
console.log('re-checked all');
this.curList.unshift('all')
}
}
//记录上一次的操作
this.preList = [...latestList]
},
// 主要用于反选的时候,精确查找到某条数据
getCurCheckedTarget(preList,latestList){
// 如果包含 all 说明是全选,需要把全部的数据赋值给他
let source = preList.includes('all') ? [...this.options.map(item => item.hospital_id)] : [...preList]
let target = [...latestList]
//遍历查找
while (source.length !== 0) {
let cur = source.shift()
if(!target.includes(cur)){
return cur
}
}
}
最终实现了 全选、取消全选、反选、全部选中即为全选的操作。
还有一种方法获取点击某个元素,给el-select绑定 visible-chang事件,当触发的时候,给下拉框的元素绑定事件,不需要每个都绑定,只给父元素绑定就行,比如事件委托,然后就知道点击的哪个了,具体可以自己试试哦
留个小问题,如果数据过多,下拉框一下子渲染出来,页面加载太慢怎么办?是否可以整个类似分页加载数据的效果呢?
自己写的不一定对或者最优,有更好的方案或问题 欢迎提出~




更多推荐
所有评论(0)