From 373e786a6b6bcf4cac0552d9fdb3a1647fd14e6d Mon Sep 17 00:00:00 2001 From: kooriookami Date: Sat, 25 May 2024 00:26:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=80=89=E9=A1=B9=E5=88=86?= =?UTF-8?q?=E7=BB=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 ++ README.md | 30 ++++---- ...{index-cvuUh5fi.css => index-BAx2GUgq.css} | 2 +- .../{index-CIoJc7Sk.js => index-BYQQjEu9.js} | 68 +++++++++---------- docs/index.html | 4 +- package-lock.json | 15 +++- packages/el-select-v2/package.json | 3 +- packages/el-select-v2/src/el-select-v2.vue | 61 ++++++++++++++++- src/components/Demo.vue | 26 ++++++- 9 files changed, 160 insertions(+), 55 deletions(-) rename docs/assets/{index-cvuUh5fi.css => index-BAx2GUgq.css} (99%) rename docs/assets/{index-CIoJc7Sk.js => index-BYQQjEu9.js} (68%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0800a9c..f0fd8fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ## Changelog +### 1.2.0 + +_2024-05-25_ + +- 添加选项分组功能 + ### 1.1.0 _2024-05-10_ diff --git a/README.md b/README.md index bbd1556..a7d19e1 100644 --- a/README.md +++ b/README.md @@ -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 + - + +
diff --git a/package-lock.json b/package-lock.json index 9cc7132..64327ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2525,6 +2525,18 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/vite": { "version": "5.2.4", "resolved": "https://registry.npmmirror.com/vite/-/vite-5.2.4.tgz", @@ -2689,11 +2701,12 @@ } }, "packages/el-select-v2": { - "version": "1.0.7", + "version": "1.1.0", "license": "ISC", "dependencies": { "element-ui": "^2.15.14", "lodash": "^4.17.21", + "uuid": "^9.0.1", "vue": "^2.7.16", "vue-virtual-scroller": "^1.1.2" } diff --git a/packages/el-select-v2/package.json b/packages/el-select-v2/package.json index 1454ef1..72e154f 100644 --- a/packages/el-select-v2/package.json +++ b/packages/el-select-v2/package.json @@ -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": { @@ -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" } diff --git a/packages/el-select-v2/src/el-select-v2.vue b/packages/el-select-v2/src/el-select-v2.vue index bf753a8..473d201 100644 --- a/packages/el-select-v2/src/el-select-v2.vue +++ b/packages/el-select-v2/src/el-select-v2.vue @@ -39,7 +39,12 @@ :key-field="valueKey" @visible="handleScrollerVisible" > +
  • {{ item[labelKey] }}
  • +
  • + +
  • 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], })); @@ -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) { @@ -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` : '', @@ -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; + } + } } diff --git a/src/components/Demo.vue b/src/components/Demo.vue index 99b5ab4..60b42f1 100644 --- a/src/components/Demo.vue +++ b/src/components/Demo.vue @@ -101,7 +101,7 @@ /> -

    自适应菜单宽度

    +

    自适应菜单宽度 (1.1.0)

    计算每一项的宽度,选择最大的作为下拉菜单宽度

    + +

    将选项进行分组 (1.2.0)

    +

    你可以为选项进行分组来区分不同的选项

    + +
    @@ -168,6 +179,7 @@ disabledOptions: [], remoteOptions: [], longOptions: [], + groupOptions: [], form: { value1: '', value2: '', @@ -179,6 +191,7 @@ value8: '', value9: [], value10: '', + value11: '', size: 'small', }, }; @@ -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 => {