前言
经常会遇到这种多选下拉框支持全选的需求,在此简单记录一下在 ElementPlus 框架下,如何使得多选的 el-select 控件支持实现全选功能。
一、示例代码
(1)/src/views/Example/ElSelect/index.vue
<template>
<div class="index">
<el-select
size="small"
placeholder="请选择游戏"
value-key="id"
style="width: 100%"
multiple
filterable
clearable
collapse-tags
:reserve-keyword="false"
collapse-tags-tooltip
v-model="gameParam.gameSelectedList"
@remove-tag="handleGameItemRemove"
>
<el-option
v-for="item in gameParam.gameList"
:key="item.id"
:label="item.name"
:title="item.name"
:value="item"
@click="handleGameItemClick(item)"
>
</el-option>
</el-select>
</div>
</template>
<script setup>
import {
h, onMounted, onUnmounted, ref, getCurrentInstance, reactive, watch, nextTick } from 'vue'
// 代理对象
const {
proxy } = getCurrentInstance()
// 游戏参数
const gameParam = reactive({
// 选中的游戏对象列表
gameSelectedList: [],
// 游戏列表
gameList: [
{
'id': 0, 'name': '全选' },
{
'id': 1, 'name': '梦幻西游' },
{
'id': 2, 'name': '暗黑破坏神2' },
{
'id': 3, 'name': '国家崛起2' },
{
'id': 4, 'name': '侠盗猎车手圣安地列斯' },
{
'id': 5, 'name': '月影传说' },
{
'id': 6, 'name': '地下城守护者2' },
],
})
/**
* 游戏改变事件句柄方法
*/
const handleGameItemClick = (item) => {
console.log('item =>', item)
// 当点击“全选”选项时
if (item.name == '全选') {
// 判断“已选列表”是否包含“全选”
let isContain = false
for (let vo of gameParam.gameSelectedList) {
if (vo.name == item.name) {
isContain = true
}
}
console.log('isContain =>', isContain)
if (isContain) {
// 若包含“全选”,则全部选中
gameParam.gameSelectedList = gameParam.gameList
} else {
// 若不包含“全选”,则全部不选中
gameParam.gameSelectedList = []
}
}
// 当点击其它选项时
else {
// 判断“已选列表”是否包含“全选”
const index = gameParam.gameSelectedList.findIndex(
(item) => item.name === '全选'
)
if (index != -1) {
console.log(gameParam.gameSelectedList.length)
console.log(gameParam.gameList.length)
if ((gameParam.gameSelectedList.length + 1) <= gameParam.gameList.length) {
gameParam.gameSelectedList.splice(index, 1)
}
} else {
console.log(gameParam.gameSelectedList.length)
console.log(gameParam.gameList.length)
if ((gameParam.gameSelectedList.length + 1) == gameParam.gameList.length) {
gameParam.gameSelectedList.push(
{
'id': 0,
'name': '全选'
}
)
}
}
}
}
/**
* 单个移除标签
*/
const handleGameItemRemove = (item) => {
console.log('item =>', item)
// 当点击“全选”选项时
if (item.name == '全选') {
// 判断“已选列表”是否包含“全选”
let isContain = false
for (let vo of gameParam.gameSelectedList) {
if (vo.name == item.name) {
isContain = true
}
}
console.log('isContain =>', isContain)
if (isContain) {
// 若包含“全选”,则全部选中
gameParam.gameSelectedList = gameParam.gameList
} else {
// 若不包含“全选”,则全部不选中
gameParam.gameSelectedList = []
}
}
// 当点击其它选项时
else {
// 判断“已选列表”是否包含“全选”
const index = gameParam.gameSelectedList.findIndex(
(item) => item.name === '全选'
)
if (index != -1) {
console.log(gameParam.gameSelectedList.length)
console.log(gameParam.gameList.length)
if ((gameParam.gameSelectedList.length + 1) <= gameParam.gameList.length) {
gameParam.gameSelectedList.splice(index, 1)
}
} else {
console.log(gameParam.gameSelectedList.length)
console.log(gameParam.gameList.length)
if ((gameParam.gameSelectedList.length + 1) == gameParam.gameList.length) {
console.log(1111)
gameParam.gameSelectedList.push(
{
'id': 0,
'name': '全选'
}
)
}
}
}
}
</script>
<style lang="less" scoped>
.index {
width: auto;
height: 100%;
padding: 0 100px;
display: grid;
align-items: center;
text-align: center;
background-color: #fafafa;
}
</style>