JsonSchema
通过配置来快速生成表单
使用案例
编辑阅读态
*
:*
:*
:*
:*
:*
:*
:*
:*
:*
:*
:*
:*
::
禁用启用
*
:*
:vue
<template>
<div>
<el-switch
v-model="switchValue"
size="large"
active-text="阅读态"
inactive-text="编辑"
@change="handleChange"
/>
<JsonSchema
ref="jsonSchemaRef"
:colon="true"
label-width="120"
wrapper-width="400"
:schema="schema"
:i-form-props="formProps"
preview-text-placeholder="当没有值的时候会显示这个文本"
/>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { onFormMount } from '@formily/core'
import { Formily } from 'element-plus-x'
const { JsonSchema } = Formily
const switchValue = ref(false)
const jsonSchemaRef = ref()
const handleChange = (value) => {
jsonSchemaRef.value.formInstance.setPattern(value ? 'readPretty' : 'editable')
}
const onSubmit = (value) => {
return new Promise((resolve) => {
setTimeout(() => {
console.log(value)
return resolve(value)
}, 1000)
})
}
const getData = () => {
return new Promise((resolve) => {
setTimeout(() => {
return resolve([
{
value: '1',
label: 'Level one 1',
children: [
{
value: '1-1',
label: 'Level two 1-1',
children: [
{
value: '1-1-1',
label: 'Level three 1-1-1',
},
],
},
],
},
{
value: '2',
label: 'Level one 2',
children: [
{
value: '2-1',
label: 'Level two 2-1',
children: [
{
value: '2-1-1',
label: 'Level three 2-1-1',
},
],
},
{
value: '2-2',
label: 'Level two 2-2',
children: [
{
value: '2-2-1',
label: 'Level three 2-2-1',
},
],
},
],
},
{
value: '3',
label: 'Level one 3',
children: [
{
value: '3-1',
label: 'Level two 3-1',
children: [
{
value: '3-1-1',
label: 'Level three 3-1-1',
},
],
},
{
value: '3-2',
label: 'Level two 3-2',
children: [
{
value: '3-2-1',
label: 'Level three 3-2-1',
},
],
},
],
},
])
}, 1000)
})
}
const options = ref([
{
label: 'Fuphoenixes',
value: 'Fuphoenixes',
},
{
label: 'kooriookami',
value: 'kooriookami',
},
{
label: 'Jeremy',
value: 'Jeremy',
},
{
label: 'btea',
value: 'btea',
},
])
const formProps = ref({
readPretty: false,
initialValues: {},
effects() {
onFormMount((form) => {
getData().then((data) => {
form.query(/(cascader|tree)/).forEach((field: any) => {
field.setDataSource?.(data)
})
})
})
},
})
const schema = {
type: 'object',
properties: {
input: {
required: true,
type: 'string',
title: '输入框',
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-component-props': {},
default: 'Summer',
},
mention: {
required: true,
type: 'string',
title: '提及',
'x-decorator': 'FormItem',
'x-component': 'Mention',
'x-component-props': {},
default: '@',
enum: options.value,
},
inputNumber: {
required: true,
type: 'number',
title: '数字',
'x-decorator': 'FormItem',
'x-component': 'InputNumber',
'x-component-props': {},
default: 10,
},
select: {
required: true,
type: 'array',
title: '选择框',
'x-decorator': 'FormItem',
'x-component': 'Select',
'x-component-props': {
multiple: true,
clearable: true,
displayType: 'text',
separator: '、',
onChange() {
console.log('select change')
},
},
enum: ['选项一', '选项二'],
default: ['选项一', '选项二', 'sfsfd'],
},
select2: {
type: 'array',
title: '虚拟选择器',
required: true,
enum: [
{ label: '选项1', value: 1 },
{ label: '选项2', value: 2 },
],
'x-decorator': 'FormItem',
'x-component': 'SelectV2',
'x-component-props': {
multiple: true,
collapseTags: true,
collapseTagsTooltip: true,
onChange() {
console.log('select2 change')
},
},
default: [1],
},
tree: {
required: true,
type: 'string',
title: '树形选择',
'x-decorator': 'FormItem',
'x-component': 'TreeSelect',
'x-component-props': {
clearable: true,
displayType: 'text',
},
default: '1-1-1',
},
cascader: {
required: true,
type: 'string',
title: '级联选择',
'x-decorator': 'FormItem',
'x-component': 'Cascader',
'x-component-props': {
clearable: true,
style: {
width: '100%',
},
},
default: '1-1-1',
},
datePicker: {
required: true,
type: 'string',
title: '日期',
'x-decorator': 'FormItem',
'x-component': 'DatePicker',
'x-component-props': {
style: {
width: '100%',
},
validateEvent: false,
'@change': function () {
console.log('datePicker change')
},
},
default: '2024/07/23',
},
timePicker: {
required: true,
type: 'string',
title: '时间',
'x-decorator': 'FormItem',
'x-component': 'TimePicker',
'x-component-props': {
style: {
width: '100%',
},
},
default: '2024/07/23 15:27:10',
},
radio: {
required: true,
type: 'string',
title: '单选框',
'x-decorator': 'FormItem',
'x-component': 'Radio.Group',
'x-component-props': {
displayType: 'text',
separator: '、',
},
enum: [
{
label: '选项1',
value: 1,
},
{
label: '选项2',
value: 2,
},
],
default: 1,
},
radio2: {
required: true,
type: 'string',
title: '单选框2',
'x-decorator': 'FormItem',
'x-component': 'Radio.Group',
'x-component-props': {
options: ['选项1', '选项2'],
},
default: '选项2',
},
checkbox: {
required: true,
type: 'array',
title: '复选框',
'x-decorator': 'FormItem',
'x-component': 'Checkbox.Group',
'x-component-props': {
displayType: 'text',
},
enum: [
{
label: '选项1',
value: 1,
},
{
label: '选项2',
value: 2,
},
],
default: [1, 2],
},
checkbox2: {
required: true,
type: 'array',
title: '复选框2',
'x-decorator': 'FormItem',
'x-component': 'Checkbox.Group',
'x-component-props': {
options: ['选项1', '选项2'],
},
default: ['选项1'],
},
switch: {
type: 'boolean',
title: '开关',
'x-decorator': 'FormItem',
'x-component': 'Switch',
'x-component-props': {
activeValue: 1,
inactiveValue: 0,
activeText: '启用',
inactiveText: '禁用',
},
default: 0,
},
textArea: {
required: true,
type: 'boolean',
title: '文本框',
'x-decorator': 'FormItem',
'x-component': 'Input.TextArea',
'x-component-props': {},
default: 'hi 你好啊',
},
slider: {
type: 'number',
title: '滑块',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Slider',
'x-component-props': {
style: {
margin: '0 4px',
},
showStops: true,
step: 10,
},
default: 10,
},
actions: {
type: 'void',
title: ' ',
'x-decorator': 'FormItem',
'x-component': 'Actions',
'x-decorator-props': {
colon: false,
},
'x-component-props': {
submitText: '提交',
resetText: '重置',
resetProps: {
forceClear: true,
},
onSubmit,
},
},
},
}
</script>
隐藏源代码
列表查询项
除了使用Space
布局也可以使用FormGrid
FormLayout
组件来进行布局,请参考各自文档
请选择
请选择
vue
<template>
<JsonSchema
ref="jsonSchemaRef"
label-width="100"
wrapper-width="320"
feedback-layout="terse"
:schema="schema"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { Formily } from 'element-plus-x'
import { Refresh, Search } from '@element-plus/icons-vue'
const { JsonSchema } = Formily
const jsonSchemaRef = ref()
const onSubmit = (value) => {
ElMessage(JSON.stringify(value, null, 2))
}
const onReset = (value) => {
ElMessage.warning(JSON.stringify(value, null, 2))
}
const options = [
{
value: '1',
label: 'Level one 1',
children: [
{
value: '1-1',
label: 'Level two 1-1',
children: [
{
value: '1-1-1',
label: 'Level three 1-1-1',
},
],
},
],
},
]
const schema = {
type: 'object',
properties: {
layout: {
type: 'void',
'x-component': 'Space',
'x-component-props': {
wrap: true,
size: 0,
},
properties: {
input: {
type: 'string',
title: '输入框',
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-component-props': {
placeholder: '请输入',
},
},
inputNumber: {
type: 'number',
title: '数字',
'x-decorator': 'FormItem',
'x-component': 'InputNumber',
'x-component-props': {
style: {
width: '100%',
},
placeholder: '0',
},
},
select: {
type: 'string',
title: '下拉选择',
'x-decorator': 'FormItem',
'x-component': 'Select',
'x-component-props': {
clearable: true,
},
enum: ['选项一', '选项二'],
},
tree: {
type: 'string',
title: '树形选择',
enum: options,
'x-decorator': 'FormItem',
'x-component': 'TreeSelect',
'x-component-props': {
clearable: true,
},
},
cascader: {
type: 'string',
title: '级联选择',
enum: options,
'x-decorator': 'FormItem',
'x-component': 'Cascader',
'x-component-props': {
clearable: true,
style: {
width: '100%',
},
},
},
datePicker: {
type: 'string',
title: '选择日期',
'x-decorator': 'FormItem',
'x-component': 'DatePicker',
'x-component-props': {
style: {
width: '100%',
},
placeholder: '请选择',
},
},
timePicker: {
type: 'string',
title: '时间',
'x-decorator': 'FormItem',
'x-component': 'TimePicker',
'x-component-props': {
style: {
width: '100%',
},
placeholder: '请选择',
},
},
actions: {
type: 'void',
title: ' ',
'x-decorator': 'FormItem',
'x-component': 'Actions',
'x-component-props': {
submitText: '搜索',
resetText: '重置',
submitProps: {
icon: Search,
},
resetProps: {
icon: Refresh,
forceClear: true,
},
onSubmit,
onReset,
},
},
},
},
},
}
</script>
隐藏源代码
自定义组件
我是自定义组件,嵌入到JsonSchema中
*
*
*
请选择
*
*
*
*
*
*
vue
<template>
<div style="height: 500px; overflow: auto">
<JsonSchema
label-width="140"
:schema="schema"
:i-form-props="formProps"
:components="components"
preview-text-placeholder="当没有值的时候会显示这个文本"
/>
</div>
</template>
<script lang="ts" setup>
import { h } from 'vue'
import { Formily } from 'element-plus-x'
import { Search } from '@element-plus/icons-vue'
const { JsonSchema } = Formily
const onSubmit = (value) => {
return new Promise((resolve) => {
setTimeout(() => {
console.log(value)
return resolve(value)
}, 1000)
})
}
const onReset = () => {
console.log('重置')
}
const formProps = {
initialValues: {
input: '123',
},
}
const CustomComp = {
name: 'CustomComp',
setup(props, { attrs, slots }) {
return () => {
return h('div', {}, [h('span', '我是自定义组件,嵌入到JsonSchema中')])
}
},
}
const components = {
CustomComp,
}
const schema = {
type: 'object',
properties: {
customComp: {
type: 'string',
title: '自定义组件',
'x-decorator': 'FormItem',
'x-component': 'CustomComp',
'x-component-props': {
style: {
width: '320px',
},
},
},
input: {
required: true,
type: 'string',
title: '输入框',
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-component-props': {
style: {
width: '320px',
},
},
},
inputNumber: {
required: true,
type: 'number',
title: '数字',
'x-decorator': 'FormItem',
'x-component': 'InputNumber',
'x-component-props': {
style: {
width: '320px',
},
},
},
select: {
required: true,
type: 'array',
title: '选择框',
'x-decorator': 'FormItem',
'x-component': 'Select',
'x-component-props': {
style: {
width: '320px',
},
multiple: true,
clearable: true,
},
enum: ['选项一', '选项二'],
},
datePicker: {
required: true,
type: 'string',
title: '日期',
'x-decorator': 'FormItem',
'x-component': 'DatePicker',
'x-component-props': {
style: {
width: '320px',
},
},
},
timePicker: {
required: true,
type: 'string',
title: '时间',
'x-decorator': 'FormItem',
'x-component': 'TimePicker',
'x-component-props': {
style: {
width: '320px',
},
},
},
radio: {
required: true,
type: 'string',
title: '单选框',
'x-decorator': 'FormItem',
'x-component': 'Radio.Group',
'x-component-props': {},
enum: [
{
label: '选项1',
value: 1,
},
{
label: '选项2',
value: 2,
},
],
},
radio1: {
required: true,
type: 'string',
title: '单选框',
'x-decorator': 'FormItem',
'x-component': 'Radio.Group',
'x-component-props': {
options: ['选项1', '选项2'],
},
},
checkbox: {
required: true,
type: 'array',
title: '复选框',
'x-decorator': 'FormItem',
'x-component': 'Checkbox.Group',
'x-component-props': {},
enum: [
{
label: '选项1',
value: 1,
},
{
label: '选项2',
value: 2,
},
],
},
checkbox1: {
required: true,
type: 'array',
title: '复选框',
'x-decorator': 'FormItem',
'x-component': 'Checkbox.Group',
'x-component-props': {
options: ['选项1', '选项2'],
},
},
switch: {
type: 'boolean',
title: '开关',
'x-decorator': 'FormItem',
'x-component': 'Switch',
},
textArea: {
type: 'boolean',
title: '文本框',
'x-decorator': 'FormItem',
'x-component': 'Input.TextArea',
'x-component-props': {
style: {
width: '320px',
},
},
},
actions: {
type: 'void',
title: ' ',
'x-decorator': 'FormItem',
'x-component': 'Actions',
'x-component-props': {
submitText: '提交',
resetText: '重置',
submitProps: {
icon: Search,
scrollToError: true,
},
onSubmit,
onReset,
},
},
},
}
</script>
隐藏源代码
API
属性名 | 说明 | 类型 | 默认值 |
---|---|---|---|
iFormProps | createForm 函数的参数值 | Object | - |
components | 自定义组件ISchemaFieldFactoryProps 类型中的 components 属性值 | Object | - |
scope | 模版编译选项 ISchemaFieldFactoryProps 类型中的 scope 属性值 | Object | - |
schema | schema 数据 | Object | - |
forceCreateForm | 是否强制创建 form 实例,不使用继承关系的 form 实例 | Object | - |
Expose
属性名 | 说明 | 参数 |
---|---|---|
formInstance | form 实例 | 用于操作各种 api |