Vue【原创】基于elementui的分组多选下拉框【group-list】

发布时间 2023-08-29 15:32:13作者: Binyy_Wuhan

效果图:

 如图分为多选模式和单选模式。

 

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>
View Code

 

调用示例:

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地址下载源码。