Skip to content

Commit

Permalink
添加 disabledKey 参数
Browse files Browse the repository at this point in the history
修复键盘导航错乱
  • Loading branch information
kooriookami committed Dec 6, 2024
1 parent 4ba3b70 commit 1387af5
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 62 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
## Changelog

### 1.4.1

_2024-12-06_

- 添加 disabledKey 参数
- 修复键盘导航错乱

### 1.4.0

_2024-11-22_
Expand Down
65 changes: 33 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,38 +53,39 @@ Vue.use(ElSelectV2);

### Select Attributes

| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|-------------------------|--------------------------------------------------|---------------------------|-------------------|-------|
| value / v-model | 绑定值 | boolean / string / number |||
| options | 列表数据 | array |||
| value-key | value 键名 | string || value |
| label-key | label 键名 | string || label |
| object-key (1.4.0) | 绑定值为对象类型时的键名 | string || value |
| min-item-size | 每个选项的最小高度 | number || 34 |
| multiple | 是否多选 | boolean || false |
| disabled | 是否禁用 | boolean || false |
| size | 输入框尺寸 | string | medium/small/mini ||
| clearable | 是否可以清空选项 | boolean || false |
| collapse-tags | 多选时是否将选中值按文字的形式展示 | boolean || false |
| multiple-limit | 多选时用户最多可以选择的项目数,为 0 则不限制 | number || 0 |
| name | select input 的 name 属性 | string |||
| autocomplete | select input 的 autocomplete 属性 | string || off |
| placeholder | 占位符 | string || 请选择 |
| filterable | 是否可搜索 | boolean || false |
| allow-create | 是否允许用户创建新条目,需配合 `filterable` 使用 | boolean || false |
| filter-method | 自定义搜索方法 | function |||
| remote | 是否为远程搜索 | boolean || false |
| remote-method | 远程搜索方法 | function |||
| loading | 是否正在从远程获取数据 | boolean || false |
| loading-text | 远程加载时显示的文字 | string || 加载中 |
| no-match-text | 搜索条件无匹配时显示的文字,也可以使用 `slot="empty"` 设置 | string || 无匹配数据 |
| no-data-text | 选项为空时显示的文字,也可以使用 `slot="empty"` 设置 | string || 无数据 |
| popper-class | Select 下拉框的类名 | string |||
| reserve-keyword | 多选且可搜索时,是否在选中一个选项后保留当前的搜索关键词 | boolean || true |
| default-first-option | 在输入框按下回车,选择第一个匹配项。需配合 `filterable``remote` 使用 | boolean || false |
| popper-append-to-body | 是否将弹出框插入至 body 元素。在弹出框的定位出现问题时,可将该属性设置为 false | boolean || true |
| automatic-dropdown | 对于不可搜索的 Select,是否在输入框获得焦点后自动弹出选项菜单 | boolean || false |
| fit-input-width (1.1.0) | 下拉框的宽度是否与输入框相同,设置为 false 后自动计算宽度,性能会有所降低 | boolean || true |
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|-------------------------|--------------------------------------------------|---------------------------|-------------------|----------|
| value / v-model | 绑定值 | boolean / string / number |||
| options | 列表数据 | array |||
| value-key | value 键名 | string || value |
| label-key | label 键名 | string || label |
| disabled-key (1.4.1) | disabled 键名 | string || disabled |
| object-key (1.4.0) | 绑定值为对象类型时的键名 | string || value |
| min-item-size | 每个选项的最小高度 | number || 34 |
| multiple | 是否多选 | boolean || false |
| disabled | 是否禁用 | boolean || false |
| size | 输入框尺寸 | string | medium/small/mini ||
| clearable | 是否可以清空选项 | boolean || false |
| collapse-tags | 多选时是否将选中值按文字的形式展示 | boolean || false |
| multiple-limit | 多选时用户最多可以选择的项目数,为 0 则不限制 | number || 0 |
| name | select input 的 name 属性 | string |||
| autocomplete | select input 的 autocomplete 属性 | string || off |
| placeholder | 占位符 | string || 请选择 |
| filterable | 是否可搜索 | boolean || false |
| allow-create | 是否允许用户创建新条目,需配合 `filterable` 使用 | boolean || false |
| filter-method | 自定义搜索方法 | function |||
| remote | 是否为远程搜索 | boolean || false |
| remote-method | 远程搜索方法 | function |||
| loading | 是否正在从远程获取数据 | boolean || false |
| loading-text | 远程加载时显示的文字 | string || 加载中 |
| no-match-text | 搜索条件无匹配时显示的文字,也可以使用 `slot="empty"` 设置 | string || 无匹配数据 |
| no-data-text | 选项为空时显示的文字,也可以使用 `slot="empty"` 设置 | string || 无数据 |
| popper-class | Select 下拉框的类名 | string |||
| reserve-keyword | 多选且可搜索时,是否在选中一个选项后保留当前的搜索关键词 | boolean || true |
| default-first-option | 在输入框按下回车,选择第一个匹配项。需配合 `filterable``remote` 使用 | boolean || false |
| popper-append-to-body | 是否将弹出框插入至 body 元素。在弹出框的定位出现问题时,可将该属性设置为 false | boolean || true |
| automatic-dropdown | 对于不可搜索的 Select,是否在输入框获得焦点后自动弹出选项菜单 | boolean || false |
| fit-input-width (1.1.0) | 下拉框的宽度是否与输入框相同,设置为 false 后自动计算宽度,性能会有所降低 | boolean || true |

### Select Events

Expand Down
48 changes: 24 additions & 24 deletions docs/assets/index-vubecb3Y.js → docs/assets/index-CGaeU_x9.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<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-vubecb3Y.js"></script>
<script type="module" crossorigin src="./assets/index-CGaeU_x9.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-D8de3ibR.css">
</head>
<body>
Expand Down
2 changes: 1 addition & 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.4.0",
"version": "1.4.1",
"main": "src/index.js",
"module": "src/index.js",
"repository": {
Expand Down
18 changes: 14 additions & 4 deletions packages/el-select-v2/src/el-select-v2.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
:key="getOptionKey(item)"
:value="item[valueKey]"
:label="item[labelKey]"
:disabled="item.disabled"
:disabled="item[disabledKey]"
>
<slot name="default" :item="item" />
</el-option>
Expand All @@ -67,13 +67,15 @@
</template>

<script>
import NavigationMixin from './navigation-mixin';
import { RecycleScroller } from 'vue-virtual-scroller';
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';
import isEqual from 'lodash/isEqual';
import isPlainObject from 'lodash/isPlainObject';
import { v4 as uuidv4 } from 'uuid';
export default {
mixins: [NavigationMixin],
name: 'ElSelectV2',
components: {
RecycleScroller,
Expand All @@ -95,6 +97,10 @@
type: String,
default: 'label',
},
disabledKey: {
type: String,
default: 'disabled',
},
objectKey: {
type: String,
default: 'value',
Expand Down Expand Up @@ -148,6 +154,7 @@
data() {
return {
localValue: '',
localIndex: -1,
localOptions: [],
dropdownWidth: '',
query: '',
Expand All @@ -156,6 +163,7 @@
mounted() {
this.updateSelectedLabel();
if (this.$refs.select) {
this.$refs.select.navigateOptions = this.navigateOptions;
this.$watch(() => this.$refs.select.visible, value => {
if (value) {
this.query = '';
Expand Down Expand Up @@ -187,10 +195,12 @@
},
handleScrollerVisible() {
const firstValue = this.multiple ? this.localValue?.[0] : this.localValue;
const index = this.localOptions.findIndex(option => this.isSameValue(option[this.valueKey], firstValue));
this.$refs.scroller.scrollToItem(index);
this.localIndex = this.localOptions.findIndex(option => this.isSameValue(option[this.valueKey], firstValue));
this.$refs.scroller.scrollToItem(this.localIndex);
this.updateHoverIndex();
},
localFilterMethod(query) {
this.localIndex = this.defaultFirstOption ? 0 : -1;
this.query = query;
if (typeof this.filterMethod === 'function') {
this.filterMethod(query);
Expand Down Expand Up @@ -300,7 +310,7 @@
handler() {
this.updateOptions();
const inputs = this.$el.querySelectorAll('input');
if ([].indexOf.call(inputs, document.activeElement) === -1) {
if (!Array.from(inputs).includes(document.activeElement)) {
this.updateSelectedLabel();
}
},
Expand Down
53 changes: 53 additions & 0 deletions packages/el-select-v2/src/navigation-mixin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
export default {
computed: {
optionsAllDisabled() {
return this.localOptions.every(option => option[this.disabledKey]);
},
},
methods: {
navigateOptions(direction) {
if (!this.$refs.select.visible) {
this.$refs.select.visible = true;
return;
}
if (!this.localOptions.length) return;
if (!this.optionsAllDisabled) {
let localOption;
if (direction === 'next') {
if (this.localIndex >= this.localOptions.length - 1) {
this.localIndex = 0;
} else {
this.localIndex++;
}
} else if (direction === 'prev') {
if (this.localIndex <= 0) {
this.localIndex = this.localOptions.length - 1;
} else {
this.localIndex--;
}
}
localOption = this.localOptions[this.localIndex];
if (localOption[this.disabledKey] || localOption._isGroup) {
this.navigateOptions(direction);
return;
}
this.$refs.scroller.scrollToItem(this.localIndex);
this.updateHoverIndex();
}
},
updateHoverIndex() {
if (!this.$refs.select) {
return;
}
this.$watch(() => this.$refs.select.options, () => {
this.$refs.select.hoverIndex = -1;
const localOption = this.localOptions[this.localIndex];
if (localOption) {
this.$refs.select.hoverIndex = this.$refs.select.options.findIndex(option => option[this.valueKey] === localOption[this.valueKey]);
}
}, {
immediate: true,
});
},
},
};

0 comments on commit 1387af5

Please sign in to comment.