diff --git a/docs/en-US/component/select.md b/docs/en-US/component/select.md
index 25cb751ac2..3e7921a814 100644
--- a/docs/en-US/component/select.md
+++ b/docs/en-US/component/select.md
@@ -21,6 +21,14 @@ select/basic-usage
:::
+## Options attribute ^(2.10.5)
+
+:::demo Shortcut from basic `el-option` usage. You can customize the alias of the `options` through the `props` attribute.
+
+select/options
+
+:::
+
## Disabled option
:::demo Set the value of `disabled` in `el-option` to `true` to disable this option.
@@ -193,56 +201,58 @@ select/custom-label
### Select Attributes
-| Name | Description | Type | Default |
-| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
-| model-value / v-model | binding value | ^[string] / ^[number] / ^[boolean] / ^[object] / ^[array] | — |
-| multiple | whether multiple-select is activated | ^[boolean] | false |
-| disabled | whether Select is disabled | ^[boolean] | false |
-| value-key | unique identity key name for value, required when value is an object | ^[string] | value |
-| size | size of Input | ^[enum]`'' \| 'large' \| 'default' \| 'small'` | — |
-| clearable | whether select can be cleared | ^[boolean] | false |
-| collapse-tags | whether to collapse tags to a text when multiple selecting | ^[boolean] | false |
-| collapse-tags-tooltip ^(2.3.0) | whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true | ^[boolean] | false |
-| multiple-limit | maximum number of options user can select when `multiple` is `true`. No limit when set to 0 | ^[number] | 0 |
-| id | native input id input | ^[string] | — |
-| name | the name attribute of select input | ^[string] | — |
-| effect | tooltip theme, built-in theme: `dark` / `light` | ^[enum]`'dark' \| 'light'` / ^[string] | light |
-| autocomplete | the autocomplete attribute of select input | ^[string] | off |
-| placeholder | placeholder, default is 'Select' | ^[string] | — |
-| filterable | whether Select is filterable | ^[boolean] | false |
-| allow-create | whether creating new items is allowed. To use this, `filterable` must be true | ^[boolean] | false |
-| filter-method | custom filter method, the first parameter is the current input value. To use this, `filterable` must be true | ^[Function]`(query: string) => void` | — |
-| remote | whether options are loaded 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]`(query: string) => void` | — |
-| remote-show-suffix | in remote search method show suffix icon | ^[boolean] | false |
-| loading | whether Select is loading data from server | ^[boolean] | false |
-| loading-text | displayed text while loading data from server, default is 'Loading' | ^[string] | — |
-| no-match-text | displayed text when no data matches the filtering query, you can also use slot `empty`, default is 'No matching data' | ^[string] | — |
-| no-data-text | displayed text when there is no options, you can also use slot `empty`, default is 'No data' | ^[string] | — |
-| popper-class | custom class name for Select's dropdown | ^[string] | '' |
-| reserve-keyword | when `multiple` and `filterable` is true, whether to reserve current keyword after selecting an option | ^[boolean] | true |
-| default-first-option | select first matching option on enter key. Use with `filterable` or `remote` | ^[boolean] | false |
-| teleported | whether select dropdown is teleported, if `true` it will be teleported to where `append-to` sets | ^[boolean] | true |
-| append-to ^(2.8.4) | which element the select dropdown appends to | ^[CSSSelector] / ^[HTMLElement] | — |
-| persistent | when select dropdown is inactive and `persistent` is `false`, select dropdown will be destroyed | ^[boolean] | true |
-| automatic-dropdown | for non-filterable Select, this prop decides if the option menu pops up when the input is focused | ^[boolean] | false |
-| clear-icon | custom clear icon component | ^[string] / ^[object]`Component` | CircleClose |
-| fit-input-width | whether the width of the dropdown is the same as the input | ^[boolean] | false |
-| suffix-icon | custom suffix icon component | ^[string] / ^[object]`Component` | ArrowDown |
-| tag-type | tag type | ^[enum]`'' \| 'success' \| 'info' \| 'warning' \| 'danger'` | info |
-| tag-effect ^(2.7.7) | tag effect | ^[enum]`'' \| 'light' \| 'dark' \| 'plain'` | light |
-| validate-event | whether to trigger form validation | ^[boolean] | true |
-| offset ^(2.8.8) | offset of the dropdown | ^[number] | 12 |
-| show-arrow ^(2.8.8) | whether the dropdown has an arrow | ^[boolean] | true |
-| placement ^(2.2.17) | position of dropdown | ^[enum]`'top' \| 'top-start' \| 'top-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end' \| 'right' \| 'right-start' \| 'right-end'` | bottom-start |
-| fallback-placements ^(2.5.6) | list of possible positions for dropdown [popper.js](https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements) | ^[array]`Placement[]` | ['bottom-start', 'top-start', 'right', 'left'] |
-| max-collapse-tags ^(2.3.0) | the max tags number to be shown. To use this, `collapse-tags` must be true | ^[number] | 1 |
-| popper-options | [popper.js](https://popper.js.org/docs/v2/) parameters | ^[object]refer to [popper.js](https://popper.js.org/docs/v2/) doc | {} |
-| aria-label ^(a11y) | same as `aria-label` in native input | ^[string] | — |
-| empty-values ^(2.7.0) | empty values of component, [see config-provider](/en-US/component/config-provider#empty-values-configurations) | ^[array] | — |
-| value-on-clear ^(2.7.0) | clear return value, [see config-provider](/en-US/component/config-provider#empty-values-configurations) | ^[string] / ^[number] / ^[boolean] / ^[Function] | — |
-| suffix-transition ^(deprecated) | animation when dropdown appears/disappears icon | ^[boolean] | true |
-| tabindex ^(2.9.0) | tabindex for input | ^[string] / ^[number] | — |
+| Name | Description | Type | Default |
+| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
+| model-value / v-model | binding value | ^[string] / ^[number] / ^[boolean] / ^[object] / ^[array] | — |
+| multiple | whether multiple-select is activated | ^[boolean] | false |
+| options ^(2.10.5) | data of the options, the key of `value` and `label` and `disabled` can be customize by `props` | ^[array]`Array<{[key: string]: any}>` | — |
+| props ^(2.10.5) | configuration options | ^[object]`{ value?: string, label?: string, disabled?: boolean}` | `{value: 'value', label: 'label', disabled: 'disabled'}` |
+| disabled | whether Select is disabled | ^[boolean] | false |
+| value-key | unique identity key name for value, required when value is an object | ^[string] | value |
+| size | size of Input | ^[enum]`'' \| 'large' \| 'default' \| 'small'` | — |
+| clearable | whether select can be cleared | ^[boolean] | false |
+| collapse-tags | whether to collapse tags to a text when multiple selecting | ^[boolean] | false |
+| collapse-tags-tooltip ^(2.3.0) | whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true | ^[boolean] | false |
+| multiple-limit | maximum number of options user can select when `multiple` is `true`. No limit when set to 0 | ^[number] | 0 |
+| id | native input id input | ^[string] | — |
+| name | the name attribute of select input | ^[string] | — |
+| effect | tooltip theme, built-in theme: `dark` / `light` | ^[enum]`'dark' \| 'light'` / ^[string] | light |
+| autocomplete | the autocomplete attribute of select input | ^[string] | off |
+| placeholder | placeholder, default is 'Select' | ^[string] | — |
+| filterable | whether Select is filterable | ^[boolean] | false |
+| allow-create | whether creating new items is allowed. To use this, `filterable` must be true | ^[boolean] | false |
+| filter-method | custom filter method, the first parameter is the current input value. To use this, `filterable` must be true | ^[Function]`(query: string) => void` | — |
+| remote | whether options are loaded 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]`(query: string) => void` | — |
+| remote-show-suffix | in remote search method show suffix icon | ^[boolean] | false |
+| loading | whether Select is loading data from server | ^[boolean] | false |
+| loading-text | displayed text while loading data from server, default is 'Loading' | ^[string] | — |
+| no-match-text | displayed text when no data matches the filtering query, you can also use slot `empty`, default is 'No matching data' | ^[string] | — |
+| no-data-text | displayed text when there is no options, you can also use slot `empty`, default is 'No data' | ^[string] | — |
+| popper-class | custom class name for Select's dropdown | ^[string] | '' |
+| reserve-keyword | when `multiple` and `filterable` is true, whether to reserve current keyword after selecting an option | ^[boolean] | true |
+| default-first-option | select first matching option on enter key. Use with `filterable` or `remote` | ^[boolean] | false |
+| teleported | whether select dropdown is teleported, if `true` it will be teleported to where `append-to` sets | ^[boolean] | true |
+| append-to ^(2.8.4) | which element the select dropdown appends to | ^[CSSSelector] / ^[HTMLElement] | — |
+| persistent | when select dropdown is inactive and `persistent` is `false`, select dropdown will be destroyed | ^[boolean] | true |
+| automatic-dropdown | for non-filterable Select, this prop decides if the option menu pops up when the input is focused | ^[boolean] | false |
+| clear-icon | custom clear icon component | ^[string] / ^[object]`Component` | CircleClose |
+| fit-input-width | whether the width of the dropdown is the same as the input | ^[boolean] | false |
+| suffix-icon | custom suffix icon component | ^[string] / ^[object]`Component` | ArrowDown |
+| tag-type | tag type | ^[enum]`'' \| 'success' \| 'info' \| 'warning' \| 'danger'` | info |
+| tag-effect ^(2.7.7) | tag effect | ^[enum]`'' \| 'light' \| 'dark' \| 'plain'` | light |
+| validate-event | whether to trigger form validation | ^[boolean] | true |
+| offset ^(2.8.8) | offset of the dropdown | ^[number] | 12 |
+| show-arrow ^(2.8.8) | whether the dropdown has an arrow | ^[boolean] | true |
+| placement ^(2.2.17) | position of dropdown | ^[enum]`'top' \| 'top-start' \| 'top-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end' \| 'right' \| 'right-start' \| 'right-end'` | bottom-start |
+| fallback-placements ^(2.5.6) | list of possible positions for dropdown [popper.js](https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements) | ^[array]`Placement[]` | ['bottom-start', 'top-start', 'right', 'left'] |
+| max-collapse-tags ^(2.3.0) | the max tags number to be shown. To use this, `collapse-tags` must be true | ^[number] | 1 |
+| popper-options | [popper.js](https://popper.js.org/docs/v2/) parameters | ^[object]refer to [popper.js](https://popper.js.org/docs/v2/) doc | {} |
+| aria-label ^(a11y) | same as `aria-label` in native input | ^[string] | — |
+| empty-values ^(2.7.0) | empty values of component, [see config-provider](/en-US/component/config-provider#empty-values-configurations) | ^[array] | — |
+| value-on-clear ^(2.7.0) | clear return value, [see config-provider](/en-US/component/config-provider#empty-values-configurations) | ^[string] / ^[number] / ^[boolean] / ^[Function] | — |
+| suffix-transition ^(deprecated) | animation when dropdown appears/disappears icon | ^[boolean] | true |
+| tabindex ^(2.9.0) | tabindex for input | ^[string] / ^[number] | — |
:::warning
diff --git a/docs/examples/select/options.vue b/docs/examples/select/options.vue
new file mode 100644
index 0000000000..09415b6871
--- /dev/null
+++ b/docs/examples/select/options.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
diff --git a/packages/components/select/__tests__/select.test.ts b/packages/components/select/__tests__/select.test.ts
index 7468c2a6bb..1fa6daff01 100644
--- a/packages/components/select/__tests__/select.test.ts
+++ b/packages/components/select/__tests__/select.test.ts
@@ -3430,4 +3430,120 @@ describe('Select', () => {
await wrapper.setData({ formDisabled: false })
expect(wrapper.find('.custom-tag').text()).toBe('enabled')
})
+
+ test('renders options via props', async () => {
+ wrapper = _mount(
+ ``,
+ () => ({
+ options: [
+ {
+ value: '选项1',
+ label: '黄金糕',
+ },
+ {
+ value: '选项2',
+ label: '双皮奶',
+ },
+ {
+ value: '选项3',
+ label: '蚵仔煎',
+ },
+ {
+ value: '选项4',
+ label: '龙须面',
+ },
+ {
+ value: '选项5',
+ label: '北京烤鸭',
+ },
+ ],
+ value: '',
+ count: 0,
+ }),
+ {
+ methods: {
+ handleChange() {
+ this.count++
+ },
+ },
+ }
+ )
+
+ await wrapper.find(`.${WRAPPER_CLASS_NAME}`).trigger('click')
+ const options = getOptions()
+ const vm = wrapper.vm as any
+ expect(vm.value).toBe('')
+ expect(wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`).text()).toBe(
+ DEFAULT_PLACEHOLDER
+ )
+ options[2].click()
+ await nextTick()
+ expect(vm.value).toBe('选项3')
+ expect(wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`).text()).toBe('蚵仔煎')
+ expect(vm.count).toBe(1)
+ options[4].click()
+ await nextTick()
+ expect(vm.value).toBe('选项5')
+ expect(wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`).text()).toBe('北京烤鸭')
+ expect(vm.count).toBe(2)
+ })
+
+ test('renders options with custom field names', async () => {
+ wrapper = _mount(
+ ``,
+ () => ({
+ options: [
+ {
+ id: 1,
+ label: '黄金糕',
+ },
+ {
+ id: 2,
+ label: '双皮奶',
+ },
+ {
+ id: 3,
+ label: '蚵仔煎',
+ },
+ {
+ id: 4,
+ label: '龙须面',
+ },
+ {
+ id: 5,
+ label: '北京烤鸭',
+ },
+ ],
+ value: '',
+ count: 0,
+ }),
+ {
+ methods: {
+ handleChange() {
+ this.count++
+ },
+ },
+ }
+ )
+
+ await wrapper.find(`.${WRAPPER_CLASS_NAME}`).trigger('click')
+ const options = getOptions()
+ const vm = wrapper.vm as any
+ expect(vm.value).toBe('')
+ expect(wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`).text()).toBe(
+ DEFAULT_PLACEHOLDER
+ )
+ options[2].click()
+ await nextTick()
+ expect(vm.value).toBe(3)
+ expect(wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`).text()).toBe('蚵仔煎')
+ expect(vm.count).toBe(1)
+ options[4].click()
+ await nextTick()
+ expect(vm.value).toBe(5)
+ expect(wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`).text()).toBe('北京烤鸭')
+ expect(vm.count).toBe(2)
+ })
})
diff --git a/packages/components/select/src/select.ts b/packages/components/select/src/select.ts
index 2b037c4a4b..92cd04ca95 100644
--- a/packages/components/select/src/select.ts
+++ b/packages/components/select/src/select.ts
@@ -270,6 +270,12 @@ export const selectProps = buildProps({
* @description which element the selection dropdown appends to
*/
appendTo: useTooltipContentProps.appendTo,
+ options: {
+ type: definePropType[]>(Array),
+ },
+ props: {
+ type: definePropType(Object),
+ },
...useEmptyValuesProps,
...useAriaProps(['ariaLabel']),
})
@@ -290,3 +296,8 @@ export type SelectProps = ExtractPropTypes
export type SelectPropsPublic = __ExtractPublicPropTypes
export type SelectEmits = EmitFn
export type SelectInstance = InstanceType & unknown
+export type SelectOptionProps = {
+ value?: string
+ label?: string
+ disabled?: string
+}
diff --git a/packages/components/select/src/select.vue b/packages/components/select/src/select.vue
index 5abeef68cf..4e3b5c64cf 100644
--- a/packages/components/select/src/select.vue
+++ b/packages/components/select/src/select.vue
@@ -276,7 +276,15 @@
:created="true"
/>
-
+
+
+