需求:
选择器组件(Select)支持多选,但是不支持全选。如果需要实现这个功能,该怎么修改呢?
方案一:下拉项增加一个【全选】,实现以下几种功能
- 下拉选项全都勾选时,【全选】自动勾选;
- 下拉选项部分勾选时,点击【全选】后,所有下拉项全部勾选;
- 下拉选项全都勾选时,点击【全选】后,所有下拉选项不勾选;
- 下拉选项和【全选】都选上的时候,不勾选任意下拉选项,【全选】按钮就不勾选了;
效果:
方案二:直接添加一个【全选】复选框,实现的功能与方案一相同
效果:
完整代码
父组件
<template> <div> <MultipleSelect :selectOptions="selectOptions" :mulSelectLoading="mulSelectLoading" :mulSelecteds="mulSelecteds" @update:updateMultipleSelect="val => mulSelecteds = val"> </MultipleSelect> <MultipleSelect2 :selectOptions="selectOptions2" :mulSelectLoading="mulSelectLoading2" :mulSelecteds="mulSelecteds2" @update:updateMultipleSelect="val => mulSelecteds2 = val"> </MultipleSelect2> </div> </template> <script> import MultipleSelect from './child.vue'; import MultipleSelect2 from './child2.vue' export default { data() { return { selectOptions:[], mulSelectLoading:false, mulSelecteds:[], selectOptions2:[], mulSelectLoading2:false, mulSelecteds2:[], } }, components:{ MultipleSelect, MultipleSelect2, }, methods: { mockData(){ this.mulSelectLoading = true; this.mulSelectLoading2 = true; setTimeout(()=>{ const options = [ { label: '上海', value: 'sh' }, { label: '南京', value: 'nj' }, { label: '重庆', value: 'cq' }, { label: '武汉', value: 'wh' }, ] this.selectOptions = options; this.mulSelectLoading = false; this.mulSelecteds = ['cq','nj']; this.selectOptions2 = options; this.mulSelectLoading2 = false; this.mulSelecteds2 = ['cq','nj']; },1500) }, }, mounted(){ this.mockData(); } } </script>
方案一:
<template> <el-select size="mini" multiple filterable :disabled="disabled" v-model='selectedArr' :loading="mulSelectLoading" :collapse-tags="collapseTags" placeholder='请选择' @change='changeSelect' @remove-tag='removeTag'> <el-option label='全选' value='全选' @click.native='selectAll' v-if="selectOptions.length"></el-option> <el-option v-for='item in selectOptions' :key='item.value' :label='item.label' :value='item.value'></el-option> </el-select> </template> <script> export default { name: 'MultipleSelect', data() { return { selectedArr: [], } }, props:{ // 选项 selectOptions:{ type:Array, default(){ return [] } }, // 是否禁用 disabled:{ type:Boolean, default:false }, // 已选中选项 mulSelecteds:{ type:Array, default(){ return [] } }, mulSelectLoading:{ type:Boolean, default:false }, collapseTags:{ type:Boolean, default:true } }, methods: { selectAll() { if (this.selectedArr.length < this.selectOptions.length) { this.selectedArr = [] this.selectOptions.map((item) => { this.selectedArr.push(item.value) }) this.selectedArr.unshift('全选'); } else { // 取消全选 this.selectedArr = []; } this.$emit('update:updateMultipleSelect',this.selectedArr); }, changeSelect(val) { if (!val.includes('全选') && val.length === this.selectOptions.length) { this.selectedArr.unshift('全选') } else if (val.includes('全选') && (val.length - 1) < this.selectOptions.length) { this.selectedArr = this.selectedArr.filter((item) => { return item !== '全选'}) } this.$emit('update:updateMultipleSelect',this.selectedArr); }, removeTag(val) { if (val === '全选') { this.selectedArr = []; this.$emit('update:updateMultipleSelect',this.selectedArr); } } }, watch:{ mulSelecteds:{ handler(newVal,oldVal){ this.selectedArr = newVal; if (!this.selectedArr.includes('全选') && this.selectedArr.length && this.selectedArr.length === this.selectOptions.length) { this.selectedArr.unshift('全选') } }, immediate: true } } } </script>
方案二:
<template> <el-select size="mini" multiple filterable :disabled="disabled" :loading="mulSelectLoading" :collapse-tags="collapseTags" v-model='selectedArr' placeholder='请选择' @change='changeSelect' > <el-checkbox v-model="checked" @change='selectAll'>全选</el-checkbox> <el-option v-for='item in selectOptions' :key='item.value' :label='item.label' :value='item.value'></el-option> </el-select> </template> <script> export default { data() { return { checked: false, selectedArr: [], } }, props:{ // 选项 selectOptions:{ type:Array, default(){ return [] } }, // 是否禁用 disabled:{ type:Boolean, default:false }, // 已选中选项 mulSelecteds:{ type:Array, default(){ return [] } }, mulSelectLoading:{ type:Boolean, default:false }, collapseTags:{ type:Boolean, default:true } }, methods: { selectAll() { this.selectedArr = []; if (this.checked) { this.selectOptions.forEach((item) => { this.selectedArr.push(item.value )}); } else { this.selectedArr = []; } this.$emit('update:updateMultipleSelect',this.selectedArr); }, changeSelect(val) { if (val.length === this.selectOptions.length) { this.checked = true; } else { this.checked = false; } this.$emit('update:updateMultipleSelect',this.selectedArr); } }, watch:{ mulSelecteds:{ handler(newVal,oldVal){ this.selectedArr = newVal; if (this.selectedArr.length && this.selectedArr.length === this.selectOptions.length) { this.checked = true; } }, immediate: true } } } </script> <style lang="stylus" scoped> .el-checkbox { text-align: right; width: 90%; } </style>
关于 select 标签拓展
定义和用法
select 元素可创建单选或多选菜单。
< select > 元素中的 < option > 标签用于定义列表中的可用选项。
属性
HTML5 中的新属性。
全局属性
< select > 标签支持 HTML 中的全局属性。
事件属性
< select > 标签支持 HTML 中的事件属性。