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地址下载源码。
Vue【原创】基于elementui的【分组多选下拉框group-select】的更多相关文章
- pentaho cde 自定义复选下拉框 checkbox select
pentaho 自带的component 虽多,但是当用户需要在一个表格中查看多个组别的数据时,pentaho自带的单选框就不能实现了,所以复选下拉框势在必行,实现效果如下: 实现原理是借用了jqu ...
- 多选下拉框(select 下拉多选)
方法一:使用multiple-select.js和multiple-select .css实现 HTML代码: <select id='checkedLevel' style="wid ...
- Easyui-Combobox多选下拉框
因为工作需要,引入combobox多选下拉框,并且获取选择的值并以","分开. 效果如下: 代码如下: <html> <head> <title> ...
- Extjs4.2 多选下拉框
//多选下拉框 Ext.define('MDM.view.custom.MultiComboBox', { extend: 'Ext.form.ComboBox', alias: 'widget.mu ...
- js:jquery multiSelect 多选下拉框实例
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- DropDownList单选与多选下拉框
一.单选DropDownList传值 1.添加界面的DropDownList显示值问题 (1)在方法内添加ViewData的方法: var ad = new UnitsRepository(); Vi ...
- Bootstrap3级联多选下拉框
<!DOCTYPE html> <html> <head> <title>Bootstrap3级联多选下拉框</title> <met ...
- js怎么能取得多选下拉框选中的多个值?
方法:获取多选下拉框对象数组→循环判断option选项的selected属性(true为选中,false为未选中)→使用value属性取出选中项的值.实例演示如下: 1.HTML结构 1 2 3 4 ...
- js多选下拉框
1.js原生实现 1.1:引用JS文件 /*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */ !function(a,b ...
- query多选下拉框插件 jquery-multiselect(修改)
其实网上关于该控件的使用教程已经很多了,其中 query多选下拉框插件 jquery-multiselect Jquery多选下拉列表插件jquery multiselect功能介绍及使用 这2个的介 ...
随机推荐
- 从零开始使用 Astro 的实用指南
在这个实用的Astro指南中,我将指导你完成设置过程,并告诉你如何构造你的文件.你将学习如何添加页面.交互式组件,甚至是markdown文章.我还会告诉你如何从服务器上获取数据,创建布局,并使用van ...
- 大三ACM第一次开会
现在是2020.9.12,单说时间的话可能感知不太强,那么换个时间, 现在是大三上.按照设想,我应该已经退役. 会上,老李的语气不再激昂,满含着无奈与沧桑.面对围在桌前的大三们,终究还是提出了那个问题 ...
- YOLOV5实时检测屏幕
YOLOV5实时检测屏幕 目录 YOLOV5实时检测屏幕 思考部分 先把原本的detect.py的代码贴在这里 分析代码并删减不用的部分 把屏幕的截图通过OpenCV进行显示 写一个屏幕截图的文件 用 ...
- PyInstaller 完美打包 Python 脚本,输出结构清晰、便于二次编辑的打包程序
引入问题 如果我要写一个 Python 项目,打包成 exe 运行(方便在没有 Python 的电脑上使用),我需要打包出的根目录结构美观,没有多余的.杂乱的依赖文件在那里碍眼,而且需要在发现 bug ...
- CANoe学习笔记(六):如何实现LIN和CAN的多帧传输-----LIN
内容: 1.实现LIN的多帧传输 一.新建一个基于LIN的CANoe工程 二.接下来创建一些工程用得上的变量.文件: 2.1 LDF文件: 这部分注意:包含三个调度表,①3C诊断请求帧②3D诊断响应帧 ...
- RLHF技术在智能娱乐中的应用:提高娱乐智能化和自动化水平”
目录 随着人工智能技术的不断发展,智能娱乐成为了人们越来越关注的话题.在智能娱乐领域中,RLHF技术的应用正在逐渐显现.本文将介绍RLHF技术在智能娱乐中的应用,提高娱乐智能化和自动化水平. 首先,我 ...
- EtherCAT 转CCLINK网关连接三菱plc应用案例
EtherCAT 现场总线协议是由德国倍福公司在 2003 年提出的,该通讯协议拓扑结构十分灵活,数据传输速度快,同步特性好,可以形成各种网络拓扑结构. 捷米特JM-ECT-CCLK 是自主研发的一 ...
- vscode中react组件
通过使用这个插件我们可以很方便的进行组件/方法/文件的导入 本篇博客仅对插件进行介绍翻译,便于自己以后使用 常用片段列表 imr: 引入 React import React from 'react' ...
- JavaScript中this的绑定
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path s ...
- ZEGO全新语音聊天室方案,2小时复刻 Clubhouse
真的火了! 新晋带货王马斯克在 Clubhouse"开房"之后,直接让 Clubhouse 爆火出圈,据说,Clubhouse 平台邀请码现在在ebay上已经卖到了快200刀一个. ...