feat: [el-select-v2]add reserve-keyword and change docs (#5308)

* feat: [el-select-v2]add reserve-keyword and change docs

* fix(components): [el-select-v2]add test case
This commit is contained in:
Alan Wang
2022-01-18 11:24:54 +08:00
committed by GitHub
parent 9117cb6fff
commit 4f9f27d40d
5 changed files with 153 additions and 58 deletions

View File

@@ -98,7 +98,15 @@ select-v2/clearable
Create and select new items that are not included in select options
:::demo By using the `allow-create` attribute, users can create new items by typing in the input box. Note that for `allow-create` to work, `filterable` must be `true`.
By using the `allow-create` attribute, users can create new items by typing in the input box. Note that for `allow-create` to work, `filterable` must be `true`.
:::tip
It will be better to set `:reserve-keyword="false"` when use `allow-create`
:::
:::demo
select-v2/allow-create
@@ -116,39 +124,37 @@ select-v2/remote-search
## SelectV2 Attributes
| Param | Description | Type | Accepted Values | Default |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | ------------------- | ------------- |
| model-value / v-model | biding value | string / number / boolean / object | — | — |
| multiple | is multiple | boolean | — | false |
| disabled | is disabled | boolean | — | false |
| value-key | unique identity key name for value, required when value is an object | string | — | value |
| size | input box size | string | large/default/small | default |
| clearable | whether select can be cleared | boolean | — | false |
| collapse-tags | whether to collapse tags to a text when multiple selecting | boolean | — | false |
| multiple-limit | maximum number of options user can select when multiple is true. No limit when set to 0 | number | | 0 |
| name | the name attribute of select input | string | — | |
| autocomplete | select input 的 autocomplete 属性 | string | — | off |
| placeholder | the autocomplete attribute of select input | string | — | Please select |
| filterable | is filterable | boolean | — | false |
| allow-create | whether creating new items is allowed. To use this, `filterable` must be true | boolean | — | false |
| no-data-text | displayed text when there is no options, you can also use slot empty | string | — | No Data |
| popper-class | custom class name for Select's dropdown | string | — | |
| popper-append-to-body | whether to append the popper menu to body. If the positioning of the popper is wrong, you can try to set this prop to false | boolean | - | false |
| popper-options | Customized popper option see more at [popper.js](https://popper.js.org/documentation.html) | object | - | - |
| automatic-dropdown | for non-filterable Select, this prop decides if the option menu pops up when the input is focused | boolean | - | false |
| clear-icon | Customized clear icon component | string / Component | | CircleClose |
| height | The height of the dropdown panel, 34px for each item | number | - | 170 |
| scrollbar-always-on | Controls whether the scrollbar is always displayed | boolean | - | false |
| Param | Description | Type | Accepted Values | Default |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | ------------------- | ------------- |
| model-value / v-model | biding value | string / number / boolean / object | — | — |
| multiple | is multiple | boolean | — | false |
| disabled | is disabled | boolean | — | false |
| value-key | unique identity key name for value, required when value is an object | string | — | value |
| size | input box size | string | large/default/small | default |
| clearable | whether select can be cleared | boolean | — | false |
| clear-icon | custom clear icon | string / component | — | CircleClose |
| collapse-tags | whether to collapse tags to a text when multiple selecting | boolean | — | false |
| multiple-limit | maximum number of options user can select when multiple is true. No limit when set to 0 | number | — | 0 |
| name | the name attribute of select input | string | — | |
| autocomplete | autocomplete of select input | string | — | off |
| placeholder | the autocomplete attribute of select input | string | — | Please select |
| filterable | is filterable | boolean | — | false |
| allow-create | whether creating new items is allowed. To use this, `filterable` must be true | boolean | — | false |
| reserve-keyword | whether reserve the keyword after select filtered option. | boolean | — | true |
| no-data-text | displayed text when there is no options, you can also use slot empty | string | | No Data |
| popper-class | custom class name for Select's dropdown | string | | |
| popper-append-to-body | whether to append the popper menu to body. If the positioning of the popper is wrong, you can try to set this prop to false | boolean | - | false |
| popper-options | Customized popper option see more at [popper.js](https://popper.js.org/documentation.html) | object | - | - |
| automatic-dropdown | for non-filterable Select, this prop decides if the option menu pops up when the input is focused | boolean | - | false |
| clear-icon | Customized clear icon component | string / Component | — | CircleClose |
| height | The height of the dropdown panel, 34px for each item | number | - | 170 |
| scrollbar-always-on | Controls whether the scrollbar is always displayed | boolean | - | false |
| remote | whether search data from server | boolean | — | false |
| remote-method | function that gets called when the input value changes. Its parameter is the current input value. To use this, `filterable` must be true | function(keyword: string) | — | — |
<span style="display: none;">
<!-- | no-match-text | 搜索条件无匹配时显示的文字,也可以使用`#empty`设置 | string | | 无匹配数据 | -->
<!-- | reserve-keyword | 多选且可搜索时是否在选中一个Option后保留当前的搜索关键词 | boolean | — | false |
| default-first-option | 在输入框按下回车,选择第一个匹配项。需配合 `filterable``remote` 使用 | boolean | - | false |
| clear-icon | 自定义清空图标的类名 | string / component | — | CircleClose |
| allow-create | 是否允许用户创建新条目,需配合 `filterable` 使用 | boolean | — | false |
<!-- | default-first-option | 在输入框按下回车,选择第一个匹配项。需配合 `filterable``remote` 使用 | boolean | - | false |
| filter-method | 自定义搜索方法 | function | — | — |
| remote | 是否为远程搜索 | boolean | — | false |
| remote-method | 远程搜索方法 | function | — | — |
| loading | 是否正在从远程获取数据 | boolean | — | false |
| loading-text | 远程加载时显示的文字 | string | — | 加载中 | -->
</span>
@@ -166,9 +172,8 @@ select-v2/remote-search
## SelectV2 Slots
| name | 说明 |
| ------- | ------------------ |
| default | Option renderer |
| empty | 无 Option 时的列表 |
<!-- | prefix | Select 组件头部内容 | -->
| name | Description |
| ------- | ----------------------------- |
| default | Option renderer |
| empty | content when options is empty |
| prefix | prefix content of input |

View File

@@ -1,23 +1,43 @@
<template>
<el-select-v2
v-model="value1"
:options="options"
placeholder="Please select"
style="width: 240px; margin-right: 16px; vertical-align: middle"
allow-create
filterable
multiple
clearable
/>
<el-select-v2
v-model="value2"
:options="options"
placeholder="Please select"
style="width: 240px; vertical-align: middle"
allow-create
filterable
clearable
/>
<div style="flex: auto">
<div>
<el-select-v2
v-model="value1"
:options="options"
placeholder="Please select"
style="width: 240px; margin-right: 16px; vertical-align: middle"
allow-create
filterable
multiple
clearable
/>
<el-select-v2
v-model="value2"
:options="options"
placeholder="Please select"
style="width: 240px; vertical-align: middle"
allow-create
filterable
clearable
/>
</div>
<div>
<p style="margin-top: 20px; margin-bottom: 8px">
set reserve-keyword false
</p>
<el-select-v2
v-model="value3"
:options="options"
placeholder="Please select"
style="width: 240px; margin-right: 16px; vertical-align: middle"
allow-create
filterable
multiple
clearable
:reserve-keyword="false"
/>
</div>
</div>
</template>
<script lang="ts" setup>
@@ -26,6 +46,7 @@ const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
const value1 = ref([])
const value2 = ref('')
const value3 = ref([])
const options = Array.from({ length: 1000 }).map((_, idx) => ({
value: `Option ${idx + 1}`,
label: `${initials[idx % 10]}${idx}`,

View File

@@ -95,6 +95,7 @@ const createSelect = (
:placeholder="placeholder"
:allow-create="allowCreate"
:remote="remote"
:reserve-keyword="reserveKeyword"
:scrollbar-always-on="scrollbarAlwaysOn"
${
options.methods && options.methods.filterMethod
@@ -129,6 +130,7 @@ const createSelect = (
multiple: false,
remote: false,
filterable: false,
reserveKeyword: false,
multipleLimit: 0,
popperAppendToBody: true,
placeholder: DEFAULT_PLACEHOLDER,
@@ -738,6 +740,70 @@ describe('Select', () => {
})
})
it('reserve-keyword', async () => {
const wrapper = createSelect({
data: () => {
return {
filterable: true,
clearable: true,
multiple: true,
reserveKeyword: true,
options: [
{
value: 'a1',
label: 'a1',
},
{
value: 'b1',
label: 'b1',
},
{
value: 'a2',
label: 'a2',
},
{
value: 'b2',
label: 'b2',
},
],
}
},
})
await nextTick()
const vm = wrapper.vm as any
await nextTick()
await wrapper.trigger('click')
const input = wrapper.find('input')
input.element.value = 'a'
await input.trigger('input')
await nextTick()
let options = getOptions()
expect(options.length).toBe(2)
options[0].click()
await nextTick()
options = getOptions()
expect(options.length).toBe(2)
input.element.value = ''
await input.trigger('input')
await nextTick()
options = getOptions()
expect(options.length).toBe(4)
vm.reserveKeyword = false
await nextTick()
input.element.value = 'a'
await input.trigger('input')
await nextTick()
options = getOptions()
expect(options.length).toBe(2)
options[0].click()
await nextTick()
options = getOptions()
expect(options.length).toBe(4)
})
it('render empty slot', async () => {
const wrapper = createSelect({
data() {

View File

@@ -51,7 +51,10 @@ export const SelectProps = {
noDataText: String,
noMatchText: String,
remoteMethod: Function,
reserveKeyword: Boolean,
reserveKeyword: {
type: Boolean,
default: true,
},
options: {
type: Array as PropType<OptionType[]>,
required: true,

View File

@@ -414,7 +414,7 @@ const useSelect = (props: ExtractPropTypes<typeof SelectProps>, emit) => {
handleQueryChange('')
states.inputLength = 20
}
if (props.filterable) {
if (props.filterable && !props.reserveKeyword) {
inputRef.value.focus?.()
onUpdateInputValue('')
}