Skip to content

Commit

Permalink
添加选项分组功能
Browse files Browse the repository at this point in the history
  • Loading branch information
kooriookami committed May 24, 2024
1 parent 35b1ef3 commit 373e786
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 55 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
## Changelog

### 1.2.0

_2024-05-25_

- 添加选项分组功能

### 1.1.0

_2024-05-10_
Expand Down
30 changes: 18 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,18 @@

```js
import Vue from 'vue';
// 必须引入 element-ui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import ElSelectV2 from 'el-select-v2';
// 必须引入 element-ui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import ElSelectV2 from 'el-select-v2';

Vue.use(ElSelectV2);
Vue.use(ElSelectV2);
```

```vue
<template>
<el-select-v2 v-model="value" :options="options" />
<el-select-v2 v-model="value" :options="options"/>
</template>
<script>
Expand Down Expand Up @@ -51,6 +52,7 @@
[示例代码](src/components/Demo.vue)

### Select Attributes

| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|-------------------------|--------------------------------------------------|---------------------------|-------------------|-------|
| value / v-model | 绑定值 | boolean / string / number |||
Expand Down Expand Up @@ -84,6 +86,7 @@
| fit-input-width (1.1.0) | 下拉框的宽度是否与输入框相同,设置为 false 后自动计算宽度,性能会有所降低 | boolean || true |

### Select Events

| 事件名称 | 说明 | 回调参数 |
|----------------|----------------------|----------------------|
| change | 选中值发生变化时触发 | 目前的选中值 |
Expand All @@ -94,21 +97,24 @@
| focus | 当 input 获得焦点时触发 | (event: Event) |

### Select Slots

| name | 说明 |
|--------|--------------------|
|| 自定义模板,参数为 { item } |
| prefix | Select 组件头部内容 |
| empty | 无选项时的列表 |


### Options
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|----------|---------------------------|----------------------|-----|-------|
| value | 选项的值 | string/number/object |||
| label | 选项的标签,若不设置则默认与 `value` 相同 | string/number |||
| disabled | 是否禁用该选项 | boolean || false |

| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|-----------------|---------------------------|----------------------|-----|-------|
| value | 选项的值 | string/number/object |||
| label | 选项的标签,若不设置则默认与 `value` 相同 | string/number |||
| options (1.2.0) | 分组选项 | array |||
| disabled | 是否禁用该选项 | boolean || false |

### Methods

| 方法名 | 说明 | 参数 |
|-------|---------------------|----|
| focus | 使 input 获取焦点 ||
Expand Down

Large diffs are not rendered by default.

68 changes: 34 additions & 34 deletions docs/assets/index-CIoJc7Sk.js → docs/assets/index-BYQQjEu9.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<link rel="icon" type="image/svg+xml" href="./vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Select V2 虚拟列表选择器</title>
<script type="module" crossorigin src="./assets/index-CIoJc7Sk.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-cvuUh5fi.css">
<script type="module" crossorigin src="./assets/index-BYQQjEu9.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-BAx2GUgq.css">
</head>
<body>
<div id="app"></div>
Expand Down
15 changes: 14 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/el-select-v2/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "el-select-v2",
"version": "1.1.0",
"version": "1.2.0",
"main": "src/index.js",
"module": "src/index.js",
"repository": {
Expand All @@ -18,6 +18,7 @@
"dependencies": {
"element-ui": "^2.15.14",
"lodash": "^4.17.21",
"uuid": "^9.0.1",
"vue": "^2.7.16",
"vue-virtual-scroller": "^1.1.2"
}
Expand Down
61 changes: 58 additions & 3 deletions packages/el-select-v2/src/el-select-v2.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@
:key-field="valueKey"
@visible="handleScrollerVisible"
>
<li v-if="item._isGroup" class="el-select-group__title">{{ item[labelKey] }}</li>
<li v-else-if="item._isSplit" class="el-select-group__split">
<span class="el-select-group__split-dash" />
</li>
<el-option
v-else
:key="item[valueKey]"
:value="item[valueKey]"
:label="item[labelKey]"
Expand All @@ -61,6 +66,7 @@
import { RecycleScroller } from 'vue-virtual-scroller';
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';
import isEqual from 'lodash/isEqual';
import { v4 as uuidv4 } from 'uuid';
export default {
name: 'ElSelectV2',
Expand Down Expand Up @@ -151,7 +157,7 @@
}
const { setSelected, cachedOptions } = this.$refs.select;
const values = this.multiple ? this.localValue : [this.localValue];
const selectedOptions = this.options.filter(option => values?.includes(option[this.valueKey])).map(option => ({
const selectedOptions = this.flattedOptions.filter(option => values?.includes(option[this.valueKey])).map(option => ({
value: option[this.valueKey],
currentLabel: option[this.labelKey],
}));
Expand All @@ -171,10 +177,17 @@
this.$refs.scroller.scrollToItem(index);
},
localFilterMethod(query) {
this.localOptions = this.options.filter(option => option[this.labelKey].toLowerCase().includes(query.toLowerCase()));
const groupNameList = this.flattedOptions.filter(option => !option._isGroup && !option._isSplit &&
option[this.labelKey]?.toLowerCase().includes(query.toLowerCase())).map(option => option._groupName);
this.localOptions = this.flattedOptions.filter(option => {
if (option._isGroup || option._isSplit) {
return groupNameList.some(groupName => option._groupName === groupName);
}
return option[this.labelKey]?.toLowerCase().includes(query.toLowerCase());
});
},
updateOptions() {
this.localOptions = this.options;
this.localOptions = this.flattedOptions;
},
async updateDropdownWidth() {
if (!this.$refs.select?.$refs.popper || this.fitInputWidth) {
Expand Down Expand Up @@ -207,6 +220,35 @@
},
},
computed: {
flattedOptions() {
if (!Array.isArray(this.options)) {
return [];
}
const list = [];
this.options.forEach(option => {
const _groupName = uuidv4();
if (Array.isArray(option.options)) {
list.push({
...option,
_isGroup: true,
_groupName,
[this.valueKey]: uuidv4(),
});
list.push(...option.options.map(subOption => ({
...subOption,
_groupName,
})));
list.push({
_isSplit: true,
_groupName,
[this.valueKey]: uuidv4(),
});
} else {
list.push(option);
}
});
return list;
},
scrollerStyle() {
return {
width: this.dropdownWidth ? `${this.dropdownWidth}px` : '',
Expand Down Expand Up @@ -265,5 +307,18 @@
.el-scrollbar__bar {
display: none;
}
.el-select-group__split {
position: relative;
.el-select-group__split-dash {
position: absolute;
left: 20px;
right: 20px;
height: 1px;
background: rgb(228, 231, 237);
top: 17px;
}
}
}
</style>
26 changes: 25 additions & 1 deletion src/components/Demo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
/>
</el-col>
<el-col :span="span">
<p class="title">自适应菜单宽度</p>
<p class="title">自适应菜单宽度 (1.1.0)</p>
<p class="description">计算每一项的宽度,选择最大的作为下拉菜单宽度</p>
<el-select-v2
v-model="form.value10"
Expand All @@ -111,6 +111,17 @@
filterable
/>
</el-col>
<el-col :span="span">
<p class="title">将选项进行分组 (1.2.0)</p>
<p class="description">你可以为选项进行分组来区分不同的选项</p>
<el-select-v2
v-model="form.value11"
:options="groupOptions"
:size="form.size"
:fit-input-width="false"
filterable
/>
</el-col>
</el-row>
</div>
<div class="form">
Expand Down Expand Up @@ -168,6 +179,7 @@
disabledOptions: [],
remoteOptions: [],
longOptions: [],
groupOptions: [],
form: {
value1: '',
value2: '',
Expand All @@ -179,6 +191,7 @@
value8: '',
value9: [],
value10: '',
value11: '',
size: 'small',
},
};
Expand All @@ -199,6 +212,17 @@
label: `long long long long long long long label ${i + 1}`,
});
}
this.groupOptions = Array.from({ length: 1000 }).map((_, idx) => {
const label = idx;
return {
value: `group ${label + 1}`,
label: `group ${label + 1}`,
options: Array.from({ length: 10 }).map((_, idx) => ({
value: `value ${idx + 1 + 10 * label}`,
label: `label ${idx + 1 + 10 * label}`,
})),
};
});
},
mounted() {
useResizeObserver(this.$refs.demoContent, entries => {
Expand Down

0 comments on commit 373e786

Please sign in to comment.