文章目录
- 实际效果
- 1.1 效果展示
- 1.2 核心功能
- Show Code
- Q & A
- 彩蛋
实际效果
1.1 效果展示
1.2 核心功能
- 区别网上其他思路,我这里不需要使用原生点击事件,将全选反选逻辑收敛在一个change事件上
此前已经看过一些全选逻辑同学尝试过后,会发现大部分是将全选的option单独定制,然后添加事件,确实可以实现目的,但是存在两个问题
A1: 全选逻辑和反选逻辑分开维护,方法太多维护成本高,不易debug
A2:自定义了全选事件需要使用原生@click.native事件,有些平台需要2次点击才能进行标签移除,交互体验就牺牲了
2. 全选选中,其他都选中,全选不选中,其他都不选
3. 除了全选都选中,则全选选中
4. 对于已经全选的标签,移除一个,全选自动移除
5. 提供调试思路、丰富的注释【热衷分享~~】
Show Code
<el-form-item label="上游服务节点:" prop="gray_server_hosts">
<el-select v-model="currentSelectedInstanceList" @change="selfAdaptInstanceSelectAllEvent"
placeholder="请选择" multiple :disabled="isEdit">
<!-- <el-option @click.native="handleSelectAll(chooseAllValue)" :label='chooseAllValue' :key="chooseAllValue" :value="chooseAllValue"></el-option> -->
<el-option v-for="item in instanceObjectArray" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
export default {
name: "FlowSwitchManage",
data() {
// 动态数据,一般是对象数组
instanceObjectArray: [],
// 当前选中的数据,一般情况是普通数组
currentSelectedInstanceList: [],
// 非响应的数据,用于保留上一次选中数据情况
preSelectOptions:[],
// 给全选打标记,1 代表全选
choose_all: 0,
chooseAllValue: '全选',
},
methods:{
selfAdaptInstanceSelectAllEvent(current) {
console.log("自动响应", current, this.choose_all, this.currentSelectedInstanceList, this.instanceObjectArray)
// 1.如果之前没有全选
// 1.1 现在有全选,全部选上
// 1.2 现在没有全选,但是数量和列表一致,全选选上
// 2.如果之前有全选
// 2.1 现在还有全选,则移除的是普通选项,则一并移除全选
// 2.2 移除的是全选,则清空
if (!this.preSelectOptions.includes(this.chooseAllValue)) {
if ((!current.includes(this.chooseAllValue) && current.length === this.instanceObjectArray.length - 1) || current.includes(this.chooseAllValue)) {
this.choose_all = 1
this.currentSelectedInstanceList = [...this.instanceObjectArray.map(option => option.value)]
}
} else if (current.includes(this.chooseAllValue) ) {
this.choose_all = 0
this.currentSelectedInstanceList = this.currentSelectedInstanceList.filter(val => val !== this.chooseAllValue)
} else if (!current.includes(this.chooseAllValue)) {
this.choose_all = 0
this.currentSelectedInstanceList = []
}
this.preSelectOptions = this.currentSelectedInstanceList
},
},
watch: {
// 'currentSelectedInstanceList' (newVal, oldVal) {
// console.log('监听instance变化', oldVal, '--->', newVal)
// this.selfAdaptInstanceSelectAllEvent()
// } 两个方式都对
// currentSelectedInstanceList: {
// handler(newVal, oldVal) {
// console.log('监听instance变化', oldVal, '--->', newVal)
// this.selfAdaptInstanceSelectAllEvent()
// },
// deep: true
// }
}
}
Q & A
作为一名后端童鞋, 根据自己的踩坑经验总结得出该设计,也借鉴不少设计,基本的注释都有,通过详细的字段名应该比较清晰,这里在回答几个问题
1、preSelectOptions 的作用在于vue是响应式的,只要你对组件变更会立刻更新mode绑定的数据,这是为什么和网上其他思路不一样,只使用一个方法解决的核心所在,如果不保存上一次的快照数据那么是无法做到用1个方法处理
2. current 和 model绑定的模型currentSelectedInstanceList数据其实一样的,这里是el组件提供方便操作而已
3. choose_all 存在的价值在于你的业务是否需要精细化控制,一般场景可以忽略
彩蛋
如果使用蚂蚁的antd-design-vue框架,a-select如何使用
data和method 不用改变,直接迁移,html使用如下即可
<a-select style="width:200px" :options="instanceObjectArray" v-model="currentSelectedInstanceList" @change="selfAdaptInstanceSelectAllEvent" placeholder="请选择" mode="multiple"/>