elementUI之下拉选项加多选框功能实现
- elementUI之下拉加多选框功能实现
- 下拉加多选框
- 升级—添加全部选项
- 需求改版完善
elementUI之下拉加多选框功能实现
因产品需求和UI样式调整,和element自带的下拉多选有冲突,索性自己尝试修改如下:
下拉加多选框
效果如下图:
封装如下:
<template><div class="select-checked"><!-- 下拉加多选框 --><el-selectv-model="value"multipleplaceholder="请选择":popper-append-to-body="false"@remove-tag="removeTag"><el-optionv-for="item in options":key="item.value":label="item.label":value="item.value"><el-checkbox v-model="item.check" @change="isChecked(item)">{{ item.label }}</el-checkbox></el-option></el-select>{{ value }}</div>
</template><script>
export default {name: 'SelectChecked',components: {},props: {options:{type: Array}},data() {return {value: []}},methods: {// 多选框触发isChecked(item) {if (item.check && this.value.indexOf(item.value) == -1) {this.value.push(item.value)} else if (!item.check) {this.value.forEach((elm, idx) => {if (elm == item.value) {this.value.splice(idx, 1)}})}this.$emit('selectedVal', this.value)},// 多选模式下移除tag时触发removeTag(value) {this.options.forEach((elm, idx) => {if (elm.value == value) {elm.check = false}})this.$emit('selectedVal', this.value)}}
}
</script><style lang="scss">
.select-checked {.el-select-dropdown.is-multiple .el-select-dropdown__item.selected::after {content: '';}.el-checkbox {width: 100%;padding: 0 30px;.el-checkbox__label {margin-left: 20px;}}.el-select-dropdown__item {padding: 0;}
}
</style>
页面中使用
<!-- -->
<template><div class="content-box"><div class="container"><SelectChecked :options="options" @selectedVal="selectedVal" /></div></div>
</template><script>
import SelectChecked from '@/components/Select/SelectChecked'
export default {name: 'record',components: {SelectChecked},data() {return {options: [{value: '001',label: '黄金糕',check: false},{value: '002',label: '双皮奶',check: false},{value: '003',label: '蚵仔煎',check: false},{value: '004',label: '龙须面',check: false},{value: '005',label: '北京烤鸭',check: false}],}},watch: { },computed: {},methods: {selectedVal(value){console.log(111, value); // 获取子组件选项的值}},created() {console.log('created-record')},activated() {console.log('created-record')},mounted() {}
}
</script><style lang="scss">
</style>
升级—添加全部选项
<template><div class="select-checked"><!-- 下拉加多选框 --><el-selectv-model="value"multipleplaceholder="请选择":popper-append-to-body="false"@remove-tag="removeTag"><el-optionv-for="item in options":key="item.value":label="item.label":value="item.value"><el-checkbox v-model="item.check" @change="isCheck(item)">{{ item.label }}</el-checkbox></el-option></el-select>{{ value }}</div>
</template><script>
export default {name: 'SelectChecked',components: {},props: {options: {type: Array}},data() {return {value: []}},methods: {// 多选框触发isCheck(item) {if (item.check && item.value == 'all') {this.value = []this.options.forEach(element => {element.check = truethis.value.push(element.value)})} else if (!item.check && item.value == 'all') {this.value = []this.options.forEach(element => {element.check = false})}if (item.check &&this.value.indexOf(item.value) == -1 &&item.value !== 'all') {this.value.forEach((elm, idx) => {if (elm == 'all') {this.value.splice(idx, 1)}})this.value.push(item.value)if (this.value.length == this.options.length - 1) {this.options[0].check = truethis.value.unshift('all')} else {this.options[0].check = false}} else if (!item.check && item.value !== 'all') {this.options[0].check = falsethis.value.forEach((elm, idx) => {if (elm == item.value || elm == 'all') {this.value.splice(idx, 1)}})}this.$emit('selectedVal', this.value)},// 多选模式下移除tag时触发removeTag(value) {if (value == 'all') {this.options.forEach((elm, idx) => {elm.check = false})this.value = []} else {this.options.forEach((elm, idx) => {if (elm.value == value || elm.value == 'all') {elm.check = false}})}this.$emit('selectedVal', this.value)}}
}
</script><style lang="scss">
.select-checked {.el-select-dropdown.is-multiple .el-select-dropdown__item.selected::after {content: '';}.el-checkbox {width: 100%;padding: 0 30px;.el-checkbox__label {margin-left: 20px;}}.el-select-dropdown__item {padding: 0;}
}
</style>
组件中使用
<!-- -->
<template><div class="content-box select-checked"><div class="container"><SelectChecked :options="options" @selectedVal="selectedVal" /></div></div>
</template><script>
import SelectChecked from '@/components/Select/SelectChecked'
export default {name: 'record',components: {SelectChecked},data() {return {options: [{value: 'all',label: '全部',check: false},{value: '001',label: '黄金糕',check: false},{value: '002',label: '双皮奶',check: false},{value: '003',label: '蚵仔煎',check: false},{value: '004',label: '龙须面',check: false},{value: '005',label: '北京烤鸭',check: false}],value1: []}},watch: {}},computed: {},methods: {selectedVal(value){// 注意这里如果有全部的话,要去掉全部value.forEach((item,idx )=>{if(item == 'all'){value.splice(idx, 1)}})console.log(111, value);}},created() {console.log('created-record')},activated() {console.log('created-record')},mounted() {}
}
</script><style lang="scss">
.select-checked {.el-select-dropdown.is-multiple .el-select-dropdown__item.selected::after {content: '';}.el-checkbox {width: 100%;padding: 0 30px;.el-checkbox__label {margin-left: 20px;}}.el-select-dropdown__item {padding: 0;}
}
</style>
效果如下图
需求改版完善
感谢龙哥指导和帮忙
<template><div class="select-checked"><el-select:value="selected"multipleplaceholder="请选择":popper-append-to-body="false"><el-option :value="''" label="全部" class="multiple"><el-checkbox v-model="optionsAll" @change="handleoptionsAllChange">全部</el-checkbox></el-option><el-optionclass="multiple":value="key":label="item"v-for="(item, key) in optionsData":key="key"><el-checkbox:value="selectedOptions.includes(key)"@change="handleTaskItemChange(key)">{{ item }}</el-checkbox></el-option></el-select></div>
</template><script>
export default {name: 'Select',components: {},props: {options: {type: Object}},data() {return {optionsData: {},optionsAll: true,selectedOptions: [],}},watch: {options: {handler(newVal) {console.log(newVal)this.optionsData = newValthis.selectedOptions = Object.keys(newVal) },immediate: true, // 该值默认是false,在进入页面时,第一次绑定值,不会立刻执行监听,只有数据发生改变才会执行handler中的操作// deep: true, // deep 深度},},computed: {selected() {if (this.selectedOptions.length === Object.keys(this.optionsData).length) {return ['']} else {return this.selectedOptions}}},methods: {handleoptionsAllChange(isAll) {if (isAll) {this.selectedOptions = Object.keys(this.optionsData)} else {this.selectedOptions = []}},handleTaskItemChange(key) {if (this.selectedOptions.includes(key)) {this.selectedOptions.splice(this.selectedOptions.indexOf(key), 1)} else {this.selectedOptions.push(key)}this.optionsAll =this.selectedOptions.length === Object.keys(this.optionsData).length}}
}
</script><style lang="scss">
.select-checked {.el-select-dropdown.is-multiple .el-select-dropdown__item.selected::after {content: '';}.el-checkbox {width: 100%;padding: 0 30px;.el-checkbox__label {margin-left: 20px;}}.el-select-dropdown__item {padding: 0;}.el-tag__close,.el-icon-close {display: none;}.el-tag.el-tag--info {background: transparent;border: 0;}.el-select {.el-select__tags {flex-wrap: nowrap;overflow: hidden;}.el-tag {background-color: #fff;border: none;color: #606266;font-size: 13px;padding-right: 0;& ~ .el-tag {margin-left: 0;}&:not(:last-child)::after {content: ',';}}}
}
</style>
组件使用:
<!-- -->
<template><div class="content-box select-checked"><div class="container"><Select :options="optionsData" @selected="selected" /></div></div>
</template><script>
import Select from '@/components/Select/Select'export default {name: 'record',components: {Select},data() {return {optionsData: {'001': '黄金糕','002': '双皮奶','003': '蚵仔煎','004': '龙须面','005': '北京烤鸭'},}},watch: {},computed: {},methods: {selected(value){console.log(value);let str = value.join()console.log(str)// 注意选项为全部时数据里面的值为空字符串和无的情况if(value.includes('') || value.length === 0){console.log(Object.keys(this.optionsData).join());}}},created() {console.log('created-record')},activated() {console.log('created-record')},mounted() {}
}
</script><style lang="scss" scoped></style>
效果如下:
因上面是对象格式数据,操作起来可能会不方便,我重新整理了一下数组对象格式数据,如下
<template><div class="select-checked"><el-select:value="selected":class="{ all: optionsAll }"multipleplaceholder="请选择":popper-append-to-body="false"><el-option :value="''" label="全部" class="multiple"><el-checkbox v-model="optionsAll" @change="handleoptionsAllChange">全部</el-checkbox></el-option><el-optionclass="multiple":value="item.value":label="item.label"v-for="(item, key) in optionsData":key="key"><el-checkbox v-model="item.check" @change="handleTaskItemChange(item)">{{ item.label }}</el-checkbox></el-option></el-select></div>
</template><script>
export default {name: 'Select',components: {},props: {options: {type: Array}},data() {return {optionsData: [],optionsAll: true,selectedOptions: []}},watch: {options: {handler(newVal) {this.optionsData = newValnewVal.forEach(item => {if (item.check) {this.selectedOptions.push(item.value)}})},immediate: true// deep: true, // 深度监听}},computed: {selected() {if (this.selectedOptions.length === this.options.length) {return ['']} else {return this.selectedOptions}}},methods: {handleoptionsAllChange(isAll) {if (isAll) {this.optionsData.forEach((elm, idx) => {elm.check = truethis.selectedOptions.push(elm.value)})} else {this.optionsData.forEach((elm, idx) => {elm.check = false})this.selectedOptions = []}this.$emit('selected',this.selectedOptions)},handleTaskItemChange(item) {// console.log(item)// 这里是取出下标的方法,可以封装写出去Array.prototype.getArrayIndex = function (obj) {for (var i = 0; i < this.length; i++) {if (this[i] === obj) {return i}}return -1}if (!item.check) {this.optionsData.forEach((elm, idx) => {if (item.value == elm.value) {let index = this.selectedOptions.getArrayIndex(item.value)this.selectedOptions.splice(index, 1)}})} else {this.optionsData.forEach((elm, idx) => {if (item.value == elm.value) {this.selectedOptions.push(elm.value)}})}this.optionsAll = this.selectedOptions.length === this.optionsData.length// console.log(this.selectedOptions, this.optionsData)this.$emit('selected', this.selectedOptions)}}
}
</script><style lang="scss">
.select-checked {.el-select-dropdown.is-multiple .el-select-dropdown__item.selected::after {content: '';}.el-checkbox {width: 100%;padding: 0 30px;.el-checkbox__label {margin-left: 20px;}}.el-select-dropdown__item {padding: 0;}.el-tag__close,.el-icon-close {display: none;}.el-tag.el-tag--info {background: transparent;border: 0;}.el-select {.el-select__tags {flex-wrap: nowrap;overflow: hidden;}.el-tag {background-color: #fff;border: none;color: #606266;font-size: 13px;padding-right: 0;& ~ .el-tag {margin-left: 0;}&:not(:last-child)::after {content: ',';}}}
}
</style>
组件中使用
<!-- -->
<template><div class="content-box select-checked"><div class="container"><Select :options="options" @selected="selected"/></div></div>
</template><script>
import SelectTest from '@/components/Select/Select'export default {name: 'record',components: {Select,},data() {return {options: [{value: '001',label: '黄金糕',check: true},{value: '002',label: '双皮奶',check: true},{value: '003',label: '蚵仔煎',check: true},{value: '004',label: '龙须面',check: true},{value: '005',label: '北京烤鸭',check: true}],}},watch: {},computed: {},methods: {selected(value){console.log(value);}},created() {console.log('created-record')},activated() {console.log('created-record')},mounted() {}
}
</script>
效果如下: