Select
Select component
Markup Schema with Synchronous Data Source Example
vue
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { FormItem, Select, Submit } from '@silver-formily/element-plus'
import { createSchemaField, FormProvider } from '@silver-formily/vue'
const form = createForm()
const { SchemaField, SchemaStringField } = createSchemaField({
components: {
FormItem,
Select,
},
})
function log(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<FormProvider :form="form">
<SchemaField>
<SchemaStringField
name="select"
title="Select"
x-decorator="FormItem"
x-component="Select"
:x-component-props="{
style: {
width: '240px',
},
}"
:enum="[
{
label: 'Option 1',
value: 1,
},
{
label: 'Option 2',
value: 2,
},
]"
/>
<SchemaStringField
name="select2"
title="Select 2"
x-decorator="FormItem"
x-component="Select"
:x-component-props="{
style: {
width: '240px',
},
}"
:enum="[
{
label: 'Option 1',
value: 1,
},
{
label: 'Option 2',
value: 2,
},
]"
/>
</SchemaField>
<Submit @submit="log">
Submit
</Submit>
</FormProvider>
</template>Select:
Select
Select 2:
Select
查看源码
Markup Schema with Async Search Example
vue
<script lang="ts" setup>
import type { DataField } from '@silver-formily/core'
import { createForm, onFieldInit, onFieldReact } from '@silver-formily/core'
import { FormItem, Select, Submit } from '@silver-formily/element-plus'
import { action, observable } from '@silver-formily/reactive'
import { createSchemaField, FormProvider } from '@silver-formily/vue'
let timeout
function fetchData(value, callback) {
if (timeout) {
clearTimeout(timeout)
timeout = null
}
function fake() {
callback([
{
label: 'AAA',
value: 'aaa',
},
{
label: 'BBB',
value: 'ccc',
},
])
}
timeout = setTimeout(fake, 300)
}
function useAsyncDataSource(pattern, service) {
const keyword = observable.ref('')
onFieldInit(pattern, (field) => {
field.setComponentProps({
remoteMethod: (value) => {
keyword.value = value
},
})
})
onFieldReact(pattern, (field: DataField) => {
field.loading = true
service({ field, keyword: keyword.value }).then(
action.bound((data) => {
field.dataSource = data
field.loading = false
}),
)
})
}
const form = createForm({
effects: () => {
useAsyncDataSource('select', async ({ keyword }) => {
if (!keyword) {
return []
}
return new Promise((resolve) => {
fetchData(keyword, resolve)
})
})
},
})
const { SchemaField, SchemaStringField } = createSchemaField({
components: {
FormItem,
Select,
},
})
function log(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<FormProvider :form="form">
<SchemaField>
<SchemaStringField
name="select"
title="Async Search Select"
x-decorator="FormItem"
x-component="Select"
:x-component-props="{
filterable: true,
remote: true,
style: {
width: '240px',
},
}"
/>
</SchemaField>
<Submit @submit="log">
Submit
</Submit>
</FormProvider>
</template>Async Search Select:
Select
查看源码
Markup Schema with Async Linked Data Source Example
vue
<script lang="ts" setup>
import type { DataField } from '@silver-formily/core'
import { createForm, onFieldReact } from '@silver-formily/core'
import { Form, FormItem, Select, Submit } from '@silver-formily/element-plus'
import { action } from '@silver-formily/reactive'
import { createSchemaField } from '@silver-formily/vue'
function useAsyncDataSource(pattern, service) {
onFieldReact(pattern, (field: DataField) => {
field.loading = true
service(field).then(
action.bound((data) => {
field.dataSource = data
field.loading = false
}),
)
})
}
const form = createForm({
effects: () => {
useAsyncDataSource('select', async (field) => {
const linkage = field.query('linkage').get('value')
if (!linkage)
return []
return new Promise((resolve) => {
setTimeout(() => {
if (linkage === 1) {
resolve([
{
label: 'AAA',
value: 'aaa',
},
{
label: 'BBB',
value: 'ccc',
},
])
}
else if (linkage === 2) {
resolve([
{
label: 'CCC',
value: 'ccc',
},
{
label: 'DDD',
value: 'ddd',
},
])
}
}, 1500)
})
})
},
})
const { SchemaField, SchemaNumberField, SchemaStringField } = createSchemaField(
{
components: {
FormItem,
Select,
},
},
)
async function onSubmit(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<Form :form="form">
<SchemaField>
<SchemaNumberField
name="linkage"
title="Linked Select"
x-decorator="FormItem"
x-component="Select"
:enum="[
{ label: 'Request 1', value: 1 },
{ label: 'Request 2', value: 2 },
]"
:x-component-props="{
style: {
width: '240px',
},
}"
/>
<SchemaStringField
name="select"
title="Async Select"
x-decorator="FormItem"
x-component="Select"
:x-component-props="{
style: {
width: '240px',
},
}"
/>
</SchemaField>
<Submit @submit="onSubmit">
Submit
</Submit>
</Form>
</template>查看源码
Markup Schema OptionGroup Example
vue
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { FormItem, Select, Submit } from '@silver-formily/element-plus'
import { createSchemaField, FormProvider } from '@silver-formily/vue'
const form = createForm()
const { SchemaField, SchemaStringField } = createSchemaField({
components: {
FormItem,
Select,
},
})
function log(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<FormProvider :form="form">
<SchemaField>
<SchemaStringField
name="select"
title="Select"
x-decorator="FormItem"
x-component="Select"
:x-component-props="{
style: {
width: '240px',
},
}"
:enum="[
{
label: 'Popular cities',
options: [
{
value: 'Shanghai',
label: 'Shanghai',
},
{
value: 'Beijing',
label: 'Beijing',
},
],
},
{
label: 'City name',
disabled: true,
options: [
{
value: 'Chengdu',
label: 'Chengdu',
},
{
value: 'Shenzhen',
label: 'Shenzhen',
},
{
value: 'Guangzhou',
label: 'Guangzhou',
},
{
value: 'Dalian',
label: 'Dalian',
},
],
},
]"
/>
</SchemaField>
<Submit @submit="log">
Submit
</Submit>
</FormProvider>
</template>Select:
Select
查看源码
JSON Schema with Synchronous Data Source Example
vue
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { Form, FormItem, Select, Submit } from '@silver-formily/element-plus'
import { createSchemaField } from '@silver-formily/vue'
const schema = {
type: 'object',
properties: {
select: {
'type': 'string',
'title': 'Select',
'enum': [
{
label: 'Option 1',
value: 1,
},
{
label: 'Option 2',
value: 2,
},
],
'x-decorator': 'FormItem',
'x-component': 'Select',
'x-component-props': {
style: 'width: 240px;',
},
},
},
}
const form = createForm()
const { SchemaField } = createSchemaField({
components: {
FormItem,
Select,
},
})
async function onSubmit(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<Form :form="form">
<SchemaField :schema="schema" />
<Submit @submit="onSubmit">
Submit
</Submit>
</Form>
</template>查看源码
JSON Schema with Async Linked Data Source Example
vue
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { Form, FormItem, Select, Submit } from '@silver-formily/element-plus'
import { action } from '@silver-formily/reactive'
import { createSchemaField } from '@silver-formily/vue'
const schema = {
type: 'object',
properties: {
linkage: {
'type': 'string',
'title': 'Linked Select',
'enum': [
{
label: 'Request 1',
value: 1,
},
{
label: 'Request 2',
value: 2,
},
],
'x-decorator': 'FormItem',
'x-component': 'Select',
'x-component-props': {
style: 'width: 240px;',
},
},
select: {
'type': 'string',
'title': 'Async Select',
'x-decorator': 'FormItem',
'x-component': 'Select',
'x-component-props': {
style: 'width: 240px;',
},
'x-reactions': ['{{useAsyncDataSource(loadData)}}'],
},
},
}
function useAsyncDataSource(service) {
return (field) => {
field.loading = true
service(field).then(
action.bound((data) => {
field.dataSource = data
field.loading = false
}),
)
}
}
async function loadData(field) {
const linkage = field.query('linkage').get('value')
if (!linkage)
return []
return new Promise((resolve) => {
setTimeout(() => {
if (linkage === 1) {
resolve([
{
label: 'AAA',
value: 'aaa',
},
{
label: 'BBB',
value: 'ccc',
},
])
}
else if (linkage === 2) {
resolve([
{
label: 'CCC',
value: 'ccc',
},
{
label: 'DDD',
value: 'ddd',
},
])
}
}, 1500)
})
}
const form = createForm()
const { SchemaField } = createSchemaField({
components: {
FormItem,
Select,
},
})
async function onSubmit(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<Form :form="form">
<SchemaField :schema="schema" :scope="{ useAsyncDataSource, loadData }" />
<Submit @submit="onSubmit">
Submit
</Submit>
</Form>
</template>查看源码
Template with Synchronous Data Source Example
vue
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { FormItem, Select, Submit } from '@silver-formily/element-plus'
import { Field, FormProvider } from '@silver-formily/vue'
const form = createForm()
function log(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<FormProvider :form="form">
<Field
name="select"
title="Select"
:decorator="[FormItem]"
:component="[
Select,
{
style: {
width: '240px',
},
},
]"
:data-source="[
{
label: 'Option 1',
value: 1,
},
{
label: 'Option 2',
value: 2,
},
]"
/>
<Submit @submit="log">
Submit
</Submit>
</FormProvider>
</template>Select:
Select
查看源码
Template with Async Linked Data Source Example
vue
<script lang="ts" setup>
import type { DataField } from '@silver-formily/core'
import { createForm, onFieldReact } from '@silver-formily/core'
import { Form, FormItem, Select, Submit } from '@silver-formily/element-plus'
import { action } from '@silver-formily/reactive'
import { Field } from '@silver-formily/vue'
function useAsyncDataSource(pattern, service) {
onFieldReact(pattern, (field: DataField) => {
field.loading = true
service(field).then(
action.bound((data) => {
field.dataSource = data
field.loading = false
}),
)
})
}
const form = createForm({
effects: () => {
useAsyncDataSource('select', async (field) => {
const linkage = field.query('linkage').get('value')
if (!linkage)
return []
return new Promise((resolve) => {
setTimeout(() => {
if (linkage === 1) {
resolve([
{
label: 'AAA',
value: 'aaa',
},
{
label: 'BBB',
value: 'ccc',
},
])
}
else if (linkage === 2) {
resolve([
{
label: 'CCC',
value: 'ccc',
},
{
label: 'DDD',
value: 'ddd',
},
])
}
}, 1500)
})
})
},
})
async function onSubmit(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<Form :form="form">
<Field
name="linkage"
title="Linked Select"
:decorator="[FormItem]"
:component="[
Select,
{
style: {
width: '240px',
},
},
]"
:data-source="[
{ label: 'Request 1', value: 1 },
{ label: 'Request 2', value: 2 },
]"
/>
<Field
name="select"
title="Async Select"
:decorator="[FormItem]"
:component="[
Select,
{
style: {
width: '240px',
},
},
]"
/>
<Submit @submit="onSubmit">
Submit
</Submit>
</Form>
</template>查看源码
Template Scoped Slot Example
vue
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { FormItem, Select, Submit } from '@silver-formily/element-plus'
import { createSchemaField, FormProvider } from '@silver-formily/vue'
const form = createForm()
const { SchemaField, SchemaStringField } = createSchemaField({
components: {
FormItem,
Select,
},
})
function log(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<FormProvider :form="form">
<SchemaField>
<SchemaStringField
name="select"
title="Select"
x-decorator="FormItem"
x-component="Select"
:x-component-props="{
style: {
width: '240px',
},
}"
:enum="[
{
label: 'Option 1',
value: 1,
},
{
label: 'Option 2',
value: 2,
},
]"
:x-content="{
option: (props, { attrs }) => `${attrs.option?.label}-${attrs.option?.value}`,
}"
/>
<SchemaStringField
name="select2"
title="Select 2"
x-decorator="FormItem"
x-component="Select"
:x-component-props="{
style: {
width: '240px',
},
}"
:enum="[
{
label: 'Option 1',
value: 1,
},
{
label: 'Option 2',
value: 2,
},
]"
/>
</SchemaField>
<Submit @submit="log">
Submit
</Submit>
</FormProvider>
</template>Select:
Select
Select 2:
Select
查看源码
Template Header Slot Example
vue
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { FormItem, Select, Submit } from '@silver-formily/element-plus'
import { Field, FormProvider } from '@silver-formily/vue'
import { ElCheckbox } from 'element-plus'
const form = createForm()
function log(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<FormProvider :form="form">
<Field
name="select"
title="Select"
:decorator="[FormItem]"
:component="[
Select,
{
style: {
width: '240px',
},
multiple: true,
},
]"
:data-source="[
{
value: 'Beijing',
label: 'Beijing',
},
{
value: 'Shanghai',
label: 'Shanghai',
},
{
value: 'Nanjing',
label: 'Nanjing',
},
{
value: 'Chengdu',
label: 'Chengdu',
},
{
value: 'Shenzhen',
label: 'Shenzhen',
},
{
value: 'Guangzhou',
label: 'Guangzhou',
},
]"
>
<template #header="{ field }">
<ElCheckbox
:indeterminate="field.value?.length > 0 && field.value?.length < field?.dataSource?.length"
@change="(value) => value ? field?.setValue(field?.dataSource?.map((item) => item.value)) : field?.setValue([])"
>
All
</ElCheckbox>
</template>
<template #footer="{ field }">
Selected City: {{ field.value?.length ?? 0 }}
</template>
</Field>
<Submit @submit="log">
Submit
</Submit>
</FormProvider>
</template>Select:
Select
查看源码
API
See https://element-plus.org/en-US/component/select.html
Extended Props
| Prop | Type | Description | Default |
|---|---|---|---|
options | SelectOptionProps[] | Option config array. In most cases, prefer configuring via dataSource. | [] |
Tip
- If an item inside
optionsalso has anoptionsarray, it is rendered as an OptionGroup. The first-level object is treated as props forElOptionGroup. See the demo for details. - If
valueKeyis not provided,labelis used as the iteration key, so make sure it is unique.
Slots
Tip
- The component inherits every slot from
ElSelect. Pay attention to the Element Plus version you are using. - The
header,footer, andtagslots additionally receivefieldin their scope. Other slots are unchanged. - The component currently cannot use the default slot of
OptionGroup.
| Slot | Description | Type |
|---|---|---|
header | Select dropdown header slot | object |
footer | Select dropdown footer slot | object |
prefix | Select prefix slot | -- |
empty | Slot displayed when there are no options | -- |
tag | Custom tag content | object |
loading | Custom loading content | -- |
label | Custom label content | object |
Object values and property selection
Set optionAsValue: true to submit option objects. The optional optionValueKeys?: string[] strictly selects top-level properties. Omit it to return complete objects; an empty array returns an empty object, and missing properties are ignored. optionAsValue defaults to false.
Projection affects only the submitted value, never dataSource. Include the identity property (value, or the configured nodeKey / rowKey) in the allowlist. Labels are resolved from the complete data source, so the form value does not need a label.
ts
const componentProps = {
optionAsValue: true,
optionValueKeys: ['value'],
}
// dataSource: [{ value: 1, label: 'One', extra: 'Business data' }]
// Form value: { value: 1 }vue
<script setup lang="ts">
import { createForm } from '@silver-formily/core'
import { FormItem, Select } from '@silver-formily/element-plus'
import { Field, FormConsumer, FormProvider } from '@silver-formily/vue'
const form = createForm()
const options = [
{ value: 1, label: 'Alpha', extra: 'Not stored in the form' },
{ value: 2, label: 'Beta', extra: 'Not stored in the form' },
]
</script>
<template>
<FormProvider :form="form">
<Field
name="choice"
title="精简对象值"
:decorator="[FormItem]"
:component="[Select, { optionAsValue: true, optionValueKeys: ['value'], clearable: true }]"
:data-source="options"
/>
<FormConsumer v-slot="{ form: currentForm }">
<pre>{{ JSON.stringify(currentForm.values, null, 2) }}</pre>
</FormConsumer>
</FormProvider>
</template>精简对象值:
Select
{}查看源码