1.需求
Select 选择器 多选需要增加 全选 和 取消全选 功能,前端框架为vue2,UI组件为elementUI。
2. 代码
- html部分
<template><el-tooltip effect="dark" :disabled="defaultValue.length <= 0" :content="defaultValue.join('、')" placement="top"><el-selectv-model="value":multiple="true"collapse-tags:disabled="disabled":placeholder="placeholder"@change="selectChange"><el-option v-if="needSelectAll && defaultOptions.length > 0" :label="selectAllLabel" :value="selectAllValue">{{ defaultOptions.length === defaultValue.length ? '取消' : '' }}{{ selectAllLabel }}</el-option><el-option v-for="(each, i) in defaultOptions" :key="i" :label="each.label" :value="each.value" /></el-select></el-tooltip>
</template>
- js部分
export default {props: {defaultValue: {type: [Array, String, Number],default() {return [];}},disabled: {type: Boolean,default() {return false;}},placeholder: {type: String,default() {return '';}},defaultOptions: {type: Array,default() {return [];}},needSelectAll: {type: Boolean,default() {return false;}},selectAllLabel: {type: String,default() {return '全部';}}},data() {return {value: [],selectAllValue: 'all全部'};},watch: {defaultValue() {this.initData();}},created() {this.initData();},methods: {updateVal(val, needEmit) {const { defaultOptions } = this;const list = defaultOptions.map(item => item.value);this.$emit('update:defaultValue', val.filter(item => list.indexOf(item) >= 0));if (needEmit) {this.$nextTick(() => {this.$emit('change', this.defaultValue);});} else { /**/ }},selectChange(val) {const { needSelectAll, selectAllValue, value, defaultValue, defaultOptions } = this;let arr = value.slice();if (needSelectAll) {arr = arr.filter(item => item !== selectAllValue);if (!this.judgeArrValEqual(arr, defaultValue)) {this.updateVal(arr);} else {if (value.indexOf(selectAllValue) >= 0) {if (arr.length < defaultOptions.length) {defaultOptions.forEach(item => {if (value.indexOf(item.value) < 0) {value.push(item.value);} else { /**/ }});this.updateVal(value.filter(item => item !== selectAllValue));} else { /**/ }} else {value.splice(0, value.length);this.updateVal([]);}}} else {if (!this.judgeArrValEqual(arr, defaultValue)) {this.updateVal(arr);} else { /**/ }}},judgeArrValEqual(list1, list2) {list1 = list1 && list1.length > 0 ? list1 : [];list2 = list2 && list2.length > 0 ? list2 : [];const arr1 = list1.slice().sort();const arr2 = list2.slice().sort();if (arr1.join(',') === arr2.join(',')) {return true;} else {return false;}},initData() {const { defaultValue, defaultOptions, value, needSelectAll, selectAllValue } = this;if (typeof defaultValue === 'string') {this.updateVal(defaultValue.split(','), false);return;} else if (typeof defaultValue === 'number') {this.updateVal([defaultValue]);return;} else { /**/ }value.splice(0, value.length);if (needSelectAll) {if (defaultValue.length === defaultOptions.length && defaultOptions.length > 0) {value.push(selectAllValue);} else {const selectAllIndex = value.indexOf(selectAllValue);if (selectAllIndex >= 0) {value.splice(selectAllIndex, 1);} else { /**/ }}} else { /**/ }value.push(...defaultValue);}}
};
3.解析
- Tooltip 文字提示 用来悬浮多选折叠提示,并设置无值时不需要提示处理。
- 在组件初始化和监听传参
defaultValue
变化时调用initData
初始化数据。 - 当选择组件数据切换时调用
selectChange
完善数据全选和取消全选。 - 通过调用
updateVal
方法出发异步数据defaultValue
更新,并按需传递change事件。
4. 具体使用
<template><SelectMultibleAll:default-value.sync="value":default-options="options":placeholder="请选择":need-select-all="needSelectAll":disabled="disabled"@change="selectChange"/>
</template><script>
import SelectMultibleAll from '@/components/SelectMultibleAll.vue';export default {components: { SelectMultibleAll },data() {return {value: [],options: [{ label: '选项1', value: '值1' },{ label: '选项2', value: '值2' }],needSelectAll: true,disabled: false}},methods: {selectChange(val) {console.log(val);}}
}
</script>
效果
代码下载