Vue【原创】基于elementui的【分组多选下拉框group-select】
效果图:
如图分为多选模式和单选模式。
group-select:
1 <template> 2 <div> 3 <el-select 4 v-model="innerValue" 5 :placeholder="placeholder" 6 @change="changeSelect" 7 :clearable="clearable" 8 :multiple="multiple" 9 :collapse-tags="collapseTags" 10 size="small" 11 popper-class="productGroupSelector" 12 > 13 <el-option-group class="productGroupSelector-group" v-for="group in options" :key="group.label" :label="group.label"> 14 <div style="display: flex; align-items: start;" v-if="multiple"> 15 <div style="display: flex;align-items: center; padding-top: 8px; padding-left: 10px"> 16 <el-checkbox v-model="group.checked" @change="selectAll($event, group.id)" :indeterminate="group.isIndeterminate"></el-checkbox> 17 </div> 18 <div> 19 <el-option 20 class="productGroupSelector-option" 21 v-for="item in group.options" 22 :key="item.value" 23 :label="item.label" 24 :value="item.value" 25 ></el-option> 26 </div> 27 </div> 28 29 <div v-else> 30 <el-option 31 class="productGroupSelector-option" 32 v-for="item in group.options" 33 :key="item.value" 34 :label="item.label" 35 :value="item.value" 36 ></el-option> 37 </div> 38 </el-option-group> 39 </el-select> 40 </div> 41 </template> 42 <script> 43 export default { 44 name: 'LiloGroupSelect', 45 model: { 46 prop: 'value', 47 event: 'change' 48 }, 49 props: { 50 value: { 51 type: [String, Array], 52 default: '' 53 }, 54 options: { 55 type: Array, 56 default() { 57 return []; 58 } 59 }, 60 placeholder: { 61 type: String, 62 default: '请选择' 63 }, 64 multiple: { 65 type: Boolean, 66 default: false 67 }, 68 clearable: { 69 type: Boolean, 70 default: false 71 }, 72 collapseTags: { 73 type: Boolean, 74 default: false 75 } 76 }, 77 data() { 78 return { 79 innerValue: '' 80 }; 81 }, 82 mounted() { 83 this.innerValue = this.value; 84 }, 85 watch: { 86 value(newVal, odlVal) { 87 this.innerValue = newVal; 88 } 89 }, 90 methods: { 91 selectAll(val, id) { 92 const selectOption = this.options.find(f => f.id === id); 93 const arr = selectOption.options.map(m => m.value); 94 if (val) { 95 if((typeof this.innerValue !== 'object') || this.innerValue.constructor !== Array) { 96 this.innerValue = []; 97 } 98 arr.forEach(item => { 99 if (!this.innerValue.includes(item)) { 100 this.innerValue.push(item); 101 } 102 }); 103 } else { 104 this.innerValue.forEach((item, index) => { 105 if (arr.includes(item)) { 106 this.innerValue.splice(index, 1, ''); 107 } 108 }); 109 } 110 this.innerValue = this.innerValue.filter(f => f !== ''); 111 if (selectOption.checked) { 112 selectOption.isIndeterminate = false; 113 } 114 this.$emit('change', this.innerValue); 115 }, 116 changeSelect(val) { 117 if (this.multiple) { 118 this.options.forEach(item => { 119 const arr = item.options.map(m => m.value); 120 item.isIndeterminate = arr.some(v => { 121 return val.some(s => s === v); 122 }); 123 item.checked = arr.every(v => { 124 return val.some(s => s === v); 125 }); 126 if (item.checked) { 127 item.isIndeterminate = false; 128 } 129 }); 130 this.$emit('change', this.innerValue); 131 } else { 132 this.$emit('change', val); 133 } 134 } 135 } 136 }; 137 </script> 138 139 <style> 140 .productGroupSelector { 141 min-width: initial !important; 142 width: 415px; 143 } 144 </style> 145 146 <style lang="scss" scoped> 147 ::v-deep { 148 .el-select-group { 149 width: 400px; 150 display: flex; 151 flex-wrap: wrap; 152 justify-content: start; 153 padding: 0px 10px; 154 } 155 156 .el-select-group__title { 157 padding-left: 20px; 158 font-size: 12px; 159 } 160 } 161 162 .productGroupSelector-group { 163 padding-top: 5px; 164 display: flex; 165 // align-items: center; 166 // flex-wrap: wrap; 167 // width: 400px; 168 padding-bottom: 5px; 169 flex-direction: column; 170 margin: 0 5px; 171 172 &:not(:last-child) { 173 border-bottom: 1px solid rgba($color: #000000, $alpha: 0.1); 174 } 175 176 &::after { 177 display: none; 178 } 179 } 180 181 .productGroupSelector-option { 182 display: inline-flex; 183 align-items: center; 184 flex-wrap: wrap; 185 } 186 187 // .productGroupSelector { 188 // .el-scrollbar__view .el-select-dropdown__list { 189 // display: flex; 190 // flex-wrap: wrap; 191 // justify-content: space-between; 192 // align-items: baseline; 193 // padding-top: 0; 194 // overflow-x: hidden; 195 // } 196 // .el-select-dropdown__wrap .el-scrollbar__wrap { 197 // max-height: 350px; 198 // } 199 // } 200 </style>
调用示例:
1 <el-row :gutter="20" class="mt-10"> 2 <el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12"> 3 <lilo-group-select :options="groupSelectOptions" @change="groupSelectChange" multiple clearable></lilo-group-select> 4 </el-col> 5 <el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12"> 6 <lilo-group-select :options="groupSelectOptions2" @change="groupSelectChange" clearable></lilo-group-select> 7 </el-col> 8 </el-row>
测试数据:
1 groupSelectOptions: [ 2 { 3 id: 1, 4 label: '热门城市', 5 checked: false, 6 isIndeterminate: false, 7 options: [ 8 { 9 value: 'Shanghai', 10 label: '上海' 11 }, 12 { 13 value: 'Beijing', 14 label: '北京' 15 } 16 ] 17 }, 18 { 19 id: 2, 20 label: '城市名', 21 checked: false, 22 isIndeterminate: false, 23 options: [ 24 { 25 value: 'Chengdu', 26 label: '成都' 27 }, 28 { 29 value: 'Shenzhen', 30 label: '深圳' 31 }, 32 { 33 value: 'Guangzhou', 34 label: '广州' 35 }, 36 { 37 value: 'Dalian', 38 label: '大连' 39 }, 40 { 41 value: 'Huizhou1', 42 label: '惠州1' 43 }, 44 { 45 value: 'Huizhou2', 46 label: '惠州2' 47 }, 48 { 49 value: 'Huizhou3', 50 label: '惠州3' 51 }, 52 { 53 value: 'Huizhou4', 54 label: '惠州4' 55 }, 56 { 57 value: 'Huizhou5', 58 label: '惠州5' 59 }, 60 { 61 value: 'Huizhou6', 62 label: '惠州6' 63 } 64 ] 65 } 66 ], 67 groupSelectOptions2: [ 68 { 69 id: 1, 70 label: '超期', 71 options: [ 72 { 73 value: 'cqwbj', 74 label: '超期未办结' 75 }, 76 { 77 value: 'ycq', 78 label: '已超期' 79 } 80 ] 81 }, 82 { 83 id: 2, 84 label: '按天', 85 options: [ 86 { 87 value: 't1', 88 label: '1天' 89 }, 90 { 91 value: 't2', 92 label: '2天' 93 }, 94 { 95 value: 't3', 96 label: '3天' 97 }, 98 { 99 value: 't4', 100 label: '4天' 101 }, 102 { 103 value: 't5', 104 label: '5天' 105 }, 106 { 107 value: 't6', 108 label: '6天' 109 }, 110 { 111 value: 't7', 112 label: '7天' 113 }, 114 { 115 value: 't8', 116 label: '8天' 117 }, 118 { 119 value: 't9', 120 label: '9天' 121 } 122 ] 123 }, 124 { 125 id: 3, 126 label: '按小时', 127 options: [ 128 { 129 value: 'h1', 130 label: '1小时' 131 }, 132 { 133 value: 'h2', 134 label: '2小时' 135 }, 136 { 137 value: 'h3', 138 label: '3小时' 139 }, 140 { 141 value: 'h4', 142 label: '4小时' 143 }, 144 { 145 value: 'h5', 146 label: '5小时' 147 }, 148 { 149 value: 'h6', 150 label: '6小时' 151 }, 152 { 153 value: 'h7', 154 label: '7小时' 155 }, 156 { 157 value: 'h8', 158 label: '8小时' 159 }, 160 { 161 value: 'h9', 162 label: '9小时' 163 } 164 ] 165 } 166 ]
1 groupSelectChange(val) { 2 console.log(val); 3 }
若代码中涉及到的工具类和图片资源,请移步页面底部的gitee地址下载源码。
作者: Binyy
出处: https://www.cnblogs.com/loveFlex
城市:wuhan
微信:momakeyy
详细源码请移步,记得点个星星噢~ https://gitee.com/binyylovesino/lilo-ui 欢迎各路大佬指导、提问~
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 原文链接 如有问题, 可邮件(408460486@qq.com)或者微信咨询.
posted on 2023-08-29 15:30 Binyy_Wuhan 阅读(643) 评论(0) 编辑 收藏 举报