需求:
选择器组件(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 中的事件属性。