JsonForm: 表单
介绍
JsonForm 是基于 ant-design-vue 的表单组件,通过 json 配置实现表单的渲染,组件内置的表单都是基于ant-design-vue 的表单组件,有Input、TextArea、InputNumber、Select、Radio、RadioGroup、Checkbox、CheckboxGroup、DatePicker、RangePicker、Switch、TreeSelect、Cascader及详情的Text跟Time组件,通过registerForm
进行全局组件注册。
js
import {
Input,
Textarea,
Switch,
Checkbox,
InputNumber,
Radio,
DatePicker,
Select,
TreeSelect,
Cascader
} from 'ant-design-vue';
import Text from './components/text.vue';
import Time from './components/time.vue';
const { RangePicker } = DatePicker;
const RadioGroup = Radio.Group;
const CheckboxGroup = Checkbox.Group;
import {
defineComponent,
h,
useModel,
reactive,
computed,
onMounted,
watch,
type Component,
} from 'vue'
// 处理 v-model:checked 绑定
export const transformBinding = (Component: Component) => {
return defineComponent({
name: Component.name,
props: {
value: {
type: Boolean,
default: false,
},
},
setup(props, { attrs, slots, emit }) {
const model = useModel(props, 'value');
watch(
() => props.value,
newValue => {
model.value = !!newValue;
},
);
return () =>
h(
Component,
{
...attrs,
checked: !!model.value,
onChange: (e: { target: { checked: boolean } }) => {
const checked = typeof e === 'object' ? e.target.checked : e;
model.value = !!checked;
emit('update:value', !!checked);
},
},
slots,
);
},
});
};
// 扩展组件,支持异步属性getOptions获取options
const extendComponentsOptions = (Component: Component, config?: any) => {
return defineComponent({
name: Component.name,
props: {
getOptions: {
type: Function,
default: undefined,
},
options: {
type: Array,
default: () => [],
},
},
setup(props, { attrs, slots }) {
const state = reactive({
options: props.options || [], // 默认使用传入的 options
});
// 过滤掉扩展属性getOptions,只保留独有的props
const selectProps = computed(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { getOptions, ...rest } = props;
return rest;
});
// 获取选项数据
const fetchOptions = async (...args: any) => {
if (!props.getOptions) return; // 如果没有提供 getOptions,直接返回
try {
const result = await props.getOptions(...args);
// 格式化选项数据,自己在接口里map处理label跟value的对应值
state.options = result;
} catch (error) {
state.options = [];
}
};
onMounted(() => {
fetchOptions();
});
watch(
() => props.options,
newOptions => {
if (newOptions && !props.getOptions) {
state.options = newOptions;
}
},
);
return () =>
h(
Component,
{
...attrs,
// treeSelect需要treeData, 需要特殊处理,正常配置options就可以
// 如有嵌套childern的话,也需要深层递归满足label跟value格式
...(Component.name === 'ATreeSelect' ? { treeData: state.options } : { options: state.options }),
...config,
...selectProps,
},
slots,
);
},
});
};
export const componentsMap = {
Text,
Time,
Textarea,
InputNumber,
DatePicker,
Input,
RangePicker,
Cascader: extendComponentsOptions(Cascader, {
allowClear: true,
showSearch: true,
getPopupContainer: (triggerNode: HTMLElement) => triggerNode.parentNode,
}),
TreeSelect: extendComponentsOptions(TreeSelect, {
allowClear: true,
showSearch: true,
getPopupContainer: (triggerNode: HTMLElement) => triggerNode.parentNode,
filterTreeNode: (inputValue: string, { label }: any) => label.indexOf(inputValue) !== -1,
}),
Select: extendComponentsOptions(Select, {
allowClear: true,
showSearch: true,
getPopupContainer: (triggerNode: HTMLElement) => triggerNode.parentNode,
}),
CheckboxGroup: extendComponentsOptions(CheckboxGroup),
RadioGroup: extendComponentsOptions(RadioGroup),
Checkbox: transformBinding(Checkbox), // 处理 v-model:checked 绑定
Switch: transformBinding(Switch), // 处理 v-model:checked 绑定
Radio: transformBinding(Radio), // 处理 v-model:checked 绑定
};
基础用法
通过注入已有的表单组件,即可实现表单的渲染,如需增加其他表单组件,可在registerForm
文件中进行增加
查看代码
vue
<template>
<JsonForm
:columns="columns"
:labelCol="{ style: { width: '100px' } }"
:rules="rules"
v-model="formData"
ref="formRef"
>
</JsonForm>
<contextHolder />
</template>
<script setup>
import { h, ref, useTemplateRef, computed } from 'vue';
import { Button, Modal } from 'ant-design-vue';
const [modal, contextHolder] = Modal.useModal();
const formRef = useTemplateRef('formRef');
const formData = ref({
projectNum: 1,
toPdt: 'beijing',
switch: true,
projectStatus: 'doing',
});
const rules = {
projectName: [{ required: true, message: '请输入项目名称' }],
toPdt: [{ required: true, message: '请选择地区' }],
};
const columns = ref([
{
label: '项目名称',
field: 'projectName',
el: 'Input',
placeholder: '输入项目名称',
},
{
label: '项目描述',
field: 'projectDesc',
el: 'Textarea',
placeholder: '输入项目描述',
},
{
label: '项目数量',
field: 'projectNum',
el: 'InputNumber',
placeholder: '输入项目数量',
min: 1,
max: 100,
style: { width: '30%' },
},
{
label: '地区',
field: 'toPdt',
el: 'Select',
placeholder: '请选择地区',
options: [
{ label: '北京', value: 'beijing' },
{ label: '上海', value: 'shanghai' },
{ label: '广州', value: 'guangzhou' },
],
},
{
label: '级联',
field: 'cascader',
el: 'Cascader',
placeholder: '请选择级联',
options: [
{
value: 'zhejiang',
label: '浙江',
children: [
{
value: 'hangzhou',
label: '杭州',
children: [
{
value: 'xihu',
label: '西湖',
},
],
},
],
},
{
value: 'jiangsu',
label: '江苏',
children: [
{
value: 'nanjing',
label: '南京',
children: [
{
value: 'zhonghuamen',
label: '中华门',
},
],
},
],
},
],
},
{
label: '节点',
field: 'node',
el: 'TreeSelect',
placeholder: '请选择节点',
treeDefaultExpandAll: true,
treeNodeFilterProp: 'label',
options: [
{
label: 'root 1',
value: 'root 1',
children: [
{
label: 'parent 1',
value: 'parent 1',
children: [
{
label: 'parent 1-0',
value: 'parent 1-0',
children: [
{
label: 'my leaf',
value: 'leaf1',
},
{
label: 'your leaf',
value: 'leaf2',
},
],
},
{
label: 'parent 1-1',
value: 'parent 1-1',
},
],
},
{
label: 'parent 2',
value: 'parent 2',
},
],
},
],
},
{
label: '项目状态',
field: 'projectStatus',
el: 'RadioGroup',
options: [
{ label: '进行中', value: 'doing' },
{ label: '已完成', value: 'done' },
{ label: '已取消', value: 'cancel' },
],
},
{
label: '项目类型',
field: 'projectType',
el: 'CheckboxGroup',
options: [
{ label: '服务', value: 'service' },
{ label: '咨询', value: 'consulting' },
],
},
{
label: '时间',
field: 'date',
el: 'RangePicker',
},
{
label: '开关',
field: 'switch',
el: 'Switch',
},
{
label: '同意条款',
field: 'checkbox',
el: 'Checkbox',
},
{
label: 'radio',
field: 'radio',
el: 'Radio',
},
{
label: '',
field: '',
style: { textAlign: 'center' },
el: h('div', [
h(
Button,
{
type: 'primary',
onClick: async () => {
await formRef.value?.validateFields();
modal.success({
title: '提交参数',
content: h(
'div',
Object.entries(formData.value).map(([key, value]) => h('div', `${key}: ${value}`)),
),
});
},
},
'提交',
),
h(
Button,
{
style: { marginLeft: '10px' },
onClick: () => {
formRef.value?.resetFields();
},
},
'重置',
),
]),
},
]);
</script>
自定义表单
支持自定义表单,通过h
函数来创建表单节点
查看代码
vue
<template>
<JsonForm :columns="columns" :labelCol="{ style: { width: '100px' } }" v-model="formData" ref="formRef"> </JsonForm>
<contextHolder />
</template>
<script setup>
import { h, useTemplateRef, ref, computed } from 'vue';
import { Input, Modal, Tooltip, Button } from 'ant-design-vue';
import { QuestionCircleOutlined } from '@ant-design/icons-vue';
const [modal, contextHolder] = Modal.useModal();
const formRef = useTemplateRef('formRef');
const formData = ref({});
const columns = [
{
label: '项目名称',
field: 'projectName',
el: h(Input),
placeholder: '输入项目名称',
},
{
label: h('span', [
h('span', '版本号'),
h(
Tooltip,
{
title: '输入多个版本号',
getPopupContainer: () => document.body,
color: 'blue',
},
h(QuestionCircleOutlined, {
style: { color: 'blue' },
}),
),
]),
field: 'toVersion',
el: h('div', [
h(Input, {
style: { width: '100%' },
placeholder: '请输入版本号',
value: computed(() => formData.value.toVersion),
onChange: e => {
formData.value.toVersion = e.target.value || undefined;
},
}),
]),
},
{
label: '',
field: '',
style: { textAlign: 'center' },
el: h(
'div',
h(
Button,
{
type: 'primary',
onClick: async () => {
await formRef.value?.validateFields();
modal.success({
title: '提交参数',
content: h(
'div',
Object.entries(formData.value).map(([key, value]) => h('div', `${key}: ${value}`)),
),
});
},
},
'提交',
),
),
},
];
</script>
异步获取表单数据
表单组件(如 Select、TreeSelect、CheckboxGroup、RadioGroup、Cascader)支持通options
属性直接配置渲染数据;新增getOptions
异步方法,可动态获取并加载表单数据,灵活适配需要远程请求的场景。需返回一个 Promise 对象,格式为:{ label: string, value: string | number }[]
查看代码
vue
<template>
<JsonForm :columns="columns" :labelCol="{ style: { width: '100px' } }" v-model="formData"> </JsonForm>
</template>
<script setup>
import { computed, reactive, ref } from 'vue';
const formData = ref({});
const columns = reactive([
{
label: '项目地址',
field: 'name',
el: 'Select',
placeholder: '请选择项目名称',
getOptions: () =>
Promise.resolve([
{ label: '项目1', value: 'project1' },
{ label: '项目2', value: 'project2' },
{ label: '项目3', value: 'project3' },
]),
},
{
label: '爱好',
field: 'hobby',
el: 'CheckboxGroup',
getOptions: () =>
Promise.resolve([
{ name: '吃饭', key: 'eat' },
{ name: '睡觉', key: 'sleep' },
{ name: '打游戏', key: 'game' },
]).then(options => options.map(item => ({ label: item.name, value: item.key }))),
},
{
label: '性别',
field: 'sex',
el: 'RadioGroup',
value: computed(() => formData.value.sex || 'female'),
onChange: e => {
formData.value.sex = e.target.value;
},
getOptions: () =>
Promise.resolve([
{ name: '男', value: 'male' },
{ name: '女', value: 'female' },
]).then(options => options.map(item => ({ ...item, label: item.name }))),
},
{
label: '节点',
field: 'node',
placeholder: '请选择节点',
el: 'TreeSelect',
treeDefaultExpandAll: true,
treeNodeFilterProp: 'label',
getOptions: () =>
Promise.resolve([
{
name: 'root 1',
value: 'root 1',
children: [
{
name: 'parent 1',
value: 'parent 1',
children: [
{
name: 'parent 1-0',
value: 'parent 1-0',
children: [
{
name: 'my leaf',
value: 'leaf1',
},
{
name: 'your leaf',
value: 'leaf2',
},
],
},
{
name: 'parent 1-1',
value: 'parent 1-1',
},
],
},
{
name: 'parent 2',
value: 'parent 2',
},
],
},
]).then(options =>
options.map(function deep(item) {
if (item.children) {
item.children = item.children.map(deep);
}
return { label: item.name, value: item.value, children: item.children };
}),
),
},
{
label: '级联',
field: 'cascader',
el: 'Cascader',
placeholder: '请选择级联',
getOptions: () =>
Promise.resolve([
{ label: '浙江', value: 'zhejiang', children: [{ label: '杭州', value: 'hangzhou' }] },
{ label: '江苏', value: 'jiangsu', children: [{ label: '南京', value: 'nanjing' }] },
])
},
]);
</script>
内置详情Text及日期Time组件
内置详情Text组件,可以使表单支持编辑跟详情使用一套代码逻辑,时间格式表单详情为Time,极大简化代码量
查看代码
vue
<template>
<div style="margin-bottom: 40px">
<a-switch v-model:checked="checked" checked-children="编辑" un-checked-children="详情" />
</div>
<JsonForm :columns="columns" :labelCol="{ style: { width: '120px' } }" v-model="formData"> </JsonForm>
</template>
<script setup>
import { computed, reactive, ref } from 'vue';
import dayjs from 'dayjs';
const checked = ref(true);
const formData = ref({
projectName: '项目名称',
projectDesc: '项目描述',
projectNums: 1,
toPdt: ['beijing', 'shanghai'],
node: 'root 1',
projectStatus: 'cancel',
projectType: ['service'],
switch: true,
checkbox: true,
date: dayjs('2022-01-01', 'YYYY-MM-DD'),
time: [dayjs('2022-02-02', 'YYYY-MM-DD'), dayjs('2022-03-03', 'YYYY-MM-DD')],
});
const columns = reactive([
{
label: 'Input',
field: 'projectName',
el: computed(() => (checked.value ? 'Input' : 'Text')),
placeholder: '输入项目名称',
},
{
label: 'Textarea',
field: 'projectDesc',
el: computed(() => (checked.value ? 'Textarea' : 'Text')),
placeholder: '输入项目描述',
},
{
label: 'InputNumber',
field: 'projectNums',
el: computed(() => (checked.value ? 'InputNumber' : 'Text')),
placeholder: '输入项目描述',
},
{
label: 'Select',
field: 'toPdt',
el: computed(() => (checked.value ? 'Select' : 'Text')),
placeholder: '请选择地区',
mode: 'multiple',
options: [
{ label: '北京', value: 'beijing' },
{ label: '上海', value: 'shanghai' },
{ label: '广州', value: 'guangzhou' },
],
},
{
label: 'TreeSelect',
field: 'node',
el: computed(() => (checked.value ? 'TreeSelect' : 'Text')),
placeholder: '请选择节点',
treeDefaultExpandAll: true,
treeNodeFilterProp: 'label',
options: [
{
label: 'root 1',
value: 'root 1',
children: [
{
label: 'parent 1',
value: 'parent 1',
children: [
{
label: 'parent 1-1',
value: 'parent 1-1',
},
],
},
{
label: 'parent 2',
value: 'parent 2',
},
],
},
],
},
{
label: 'RadioGroup',
field: 'projectStatus',
el: computed(() => (checked.value ? 'RadioGroup' : 'Text')),
options: [
{ label: '进行中', value: 'doing' },
{ label: '已完成', value: 'done' },
{ label: '已取消', value: 'cancel' },
],
},
{
label: 'CheckboxGroup',
field: 'projectType',
el: computed(() => (checked.value ? 'CheckboxGroup' : 'Text')),
options: [
{ label: '服务', value: 'service' },
{ label: '咨询', value: 'consulting' },
],
},
{
label: 'Switch',
field: 'switch',
el: computed(() => (checked.value ? 'Switch' : 'Text')),
},
{
label: 'Checkbox',
field: 'checkbox',
el: computed(() => (checked.value ? 'Checkbox' : 'Text')),
},
{
label: 'DatePicker',
field: 'date',
el: computed(() => (checked.value ? 'DatePicker' : 'Time')),
},
{
label: 'RangePicker',
field: 'time',
el: computed(() => (checked.value ? 'RangePicker' : 'Time')),
},
]);
</script>
动态增减自定义表格
查看代码
vue
<template>
<div style="margin-bottom: 40px">
<a-switch v-model:checked="checked" checked-children="编辑" un-checked-children="详情" />
</div>
<JsonForm :columns="columns" :labelCol="{ style: { width: '70px' } }" v-model="formData" ref="formRef"> </JsonForm>
<contextHolder />
</template>
<script setup>
import { h, useTemplateRef, ref, reactive, computed } from 'vue';
import { Modal, Button } from 'ant-design-vue';
import Table from './components/table.vue';
const [modal, contextHolder] = Modal.useModal();
const formRef = useTemplateRef('formRef');
const checked = ref(true);
const formData = reactive({
address: [
{
city: '中国',
phone: '12345678901',
},
],
});
const columns = reactive([
{
label: '姓名',
field: 'projectName',
el: computed(() => (checked.value ? 'Input' : 'Text')),
placeholder: '请输入姓名',
span: 12,
},
{
label: '手机号',
field: 'projectNo',
el: computed(() => (checked.value ? 'Input' : 'Text')),
placeholder: '请输入手机号',
span: 12,
},
{
label: '地址',
field: 'address',
el: h(Table),
isEdit: checked,
},
{
label: '',
field: '',
isShow: checked,
style: { textAlign: 'center' },
el: h(
'div',
h(
Button,
{
type: 'primary',
onClick: async () => {
await formRef.value?.validateFields();
modal.success({
title: '提交参数',
content: h(
'div',
Object.entries(formData).map(([key, value]) => h('div', `${key}: ${JSON.stringify(value)}`)),
),
});
},
},
'提交',
),
),
},
]);
</script>
vue
<template>
<a-table :columns="columns" :data-source="data" :pagination="false" />
<a-button danger style="width: 100%" @click="addRow" v-if="checked">添加一行</a-button>
</template>
<script setup>
import { Input } from 'ant-design-vue';
import { h, reactive, useModel, watch, ref } from 'vue';
import { Form } from 'ant-design-vue';
const formItemContext = Form.useInjectFormItemContext();
const props = defineProps({
value: {
type: Array,
default: () => [],
},
isEdit: {
type: Boolean,
default: true,
},
});
const model = useModel(props, 'value');
const data = reactive([]);
const checked = ref(true);
watch(
() => props.value,
newValue => {
data.length = 0;
(newValue || []).forEach((item, index) => {
data.push({
key: `${index + 1}`,
city: item.city || '',
phone: item.phone || '',
});
});
},
{ immediate: true, deep: true },
);
watch(
() => props.isEdit,
newValue => {
checked.value = newValue;
},
);
const addRow = () => {
data.push({
key: `${data.length + 1}`,
city: '',
phone: '',
});
model.value = JSON.parse(JSON.stringify(data));
formItemContext.onFieldChange();
};
const handleChange = (name, value, index) => {
if (!data[index]) return;
data[index][name] = value;
model.value = JSON.parse(JSON.stringify(data));
formItemContext.onFieldChange();
};
const columns = reactive([
{
title: '地址',
dataIndex: 'city',
width: 190,
customRender: ({ _, record, index }) =>
checked.value
? h(
Form.Item,
{
name: ['address', index, 'city'],
rules: [{ required: true, message: '请输入地址' }],
},
h(Input, {
placeholder: '请输入地址',
value: data[index]?.city || '',
onChange: e => handleChange('city', e.target.value, index),
}),
)
: h('span', data[index]?.city || ''),
},
{
title: '手机号',
dataIndex: 'phone',
width: 190,
customRender: ({ _, record, index }) =>
checked.value
? h(
Form.Item,
{
name: ['address', index, 'phone'],
rules: [{ required: true, message: '请输入手机号' }],
},
h(Input, {
placeholder: '请输入手机号',
value: data[index]?.phone || '',
onChange: e => handleChange('phone', e.target.value, index),
}),
)
: h('span', data[index]?.phone || ''),
},
{
title: '操作',
dataIndex: 'action',
width: 190,
customRender: ({ _, record, index }) =>
checked.value
? h(
'span',
{
style: { color: '#1890ff', cursor: 'pointer' },
onClick: () => {
data.splice(index, 1).forEach((_, i) => (data[i].key = `${i + 1}`));
model.value = JSON.parse(JSON.stringify(data));
formItemContext.onFieldChange();
},
},
'删除',
)
: h('span', '--'),
},
]);
</script>
高级搜索
查看代码
vue
<template>
<JsonForm
:columns="columns.slice(0, expand ? columns.length : 6)"
:labelCol="{ style: { width: '40px' } }"
:wrapperCol="{ style: { width: '100px' } }"
layout="inline"
class="search-form"
:span="8"
>
<div style="margin-top: 15px">
<a-button type="primary">查询</a-button>
<a-button style="margin: 0 8px">重置</a-button>
<a style="font-size: 12px" @click="expand = !expand">
<template v-if="expand">
<UpOutlined />
</template>
<template v-else>
<DownOutlined />
</template>
高级搜索
</a>
</div>
</JsonForm>
</template>
<script setup>
import { reactive, ref } from 'vue';
import { DownOutlined, UpOutlined } from '@ant-design/icons-vue';
const expand = ref(false);
const columns = reactive([
{
label: '姓名',
field: 'projectName',
el: 'Input',
placeholder: '请输入姓名',
},
{
label: '姓名',
field: 'projectName',
el: 'Input',
placeholder: '请输入姓名',
},
{
label: '姓名',
field: 'projectName',
el: 'Input',
placeholder: '请输入姓名',
},
{
label: '姓名',
field: 'projectName',
el: 'Input',
placeholder: '请输入姓名',
},
{
label: '姓名',
field: 'projectName',
el: 'Input',
placeholder: '请输入姓名',
},
{
label: '姓名',
field: 'projectName',
el: 'Input',
placeholder: '请输入姓名',
},
{
label: '姓名',
field: 'projectName',
el: 'Input',
placeholder: '请输入姓名',
},
{
label: '姓名',
field: 'projectName',
el: 'Input',
placeholder: '请输入姓名',
},
{
label: '姓名',
field: 'projectName',
el: 'Input',
placeholder: '请输入姓名',
},
{
label: '姓名',
field: 'projectName',
el: 'Input',
placeholder: '请输入姓名',
},
]);
</script>
<style scoped>
.search-form {
justify-content: flex-end;
}
</style>
布局
禁用:
查看代码
vue
<template>
<div style="margin-bottom: 40px">
<a-radio-group v-model:value="layout" button-style="solid">
<a-radio-button value="horizontal">Horizontal</a-radio-button>
<a-radio-button value="vertical">Vertical</a-radio-button>
<a-radio-button value="inline">Inline</a-radio-button>
</a-radio-group>
<span style="margin: 0 20px">禁用: <a-switch v-model:checked="disabled" /></span>
<a-radio-group v-model:value="col" button-style="solid">
<a-radio-button :value="1">1列</a-radio-button>
<a-radio-button :value="2">2列</a-radio-button>
<a-radio-button :value="3">3列</a-radio-button>
</a-radio-group>
</div>
<JsonForm
:columns="columns"
:labelCol="{ style: { width: '100px' } }"
:disabled="disabled"
:layout="layout"
:span="span"
>
</JsonForm>
</template>
<script setup>
import { ref, computed } from 'vue';
const layout = ref('horizontal');
const disabled = ref(false);
const col = ref(1);
const span = computed(() => {
return Number(24 / col.value);
});
const columns = [
{
label: '项目名称',
field: 'projectName',
el: 'Input',
placeholder: '输入项目名称',
},
{
label: '项目描述',
field: 'projectDesc',
el: 'Textarea',
placeholder: '输入项目描述',
},
{
label: '项目状态',
field: 'projectStatus',
el: 'Select',
placeholder: '选择项目状态',
options: [
{ label: '进行中', value: '进行中' },
{ label: '已完成', value: '已完成' },
{ label: '已取消', value: '已取消' },
],
},
{
label: '项目负责人',
field: 'projectLeader',
el: 'Select',
placeholder: '选择项目负责人',
options: [
{ label: '张三', value: '张三' },
{ label: '李四', value: '李四' },
{ label: '王五', value: '王五' },
],
},
{
label: '开始日期',
field: 'startDate',
el: 'DatePicker',
placeholder: '选择开始日期',
},
{
label: '结束日期',
field: 'endDate',
el: 'DatePicker',
placeholder: '选择结束日期',
},
];
</script>
API
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
columns | FormItem[] | 无 | 表单列配置数组 |
span | number | 无 | a-col 组件的 span 属性,用于控制表单项的布局个数 |
其余参数同 antd form 一样 | --- | --- | 参考 antd form |
columns 参数
参数名 | 类型 | 说明 |
---|---|---|
el | string | Function | 表单项使用的组件名称(在 registerForm 文件中查看枚举)或自定义组件函数或 h 函数生成组件 |
label | string | 表单项的标签文本 |
field | string | 同表单绑定的 v-model:value 或者 v-model:checked |
value | any | 表单项的默认值 |
isShow | boolean | 表单项的显示隐藏 |
getOptions | Promise.resolve | 表单项有 options 配置的可以通过 getOptions 函数异步拿取 options 并将数据 return 为 Array<{label:'显示标题', value:'值'}> |
剩余表单 props | any | 表单项各自的属性的配置可直接作用到表单项上 |
引入组件可以通过 import 来导入,或者内部的 hook 方式引入组件,抛出的实例可根据业务进行自己增加或者修改
js
<template>
<JsonForm />
</template>
import { useForm } from '@/components/Form/useForm';
import { JsonForm, validateFields } = useForm()
registerForm 可根据需要进行增加全局通用的表单组件进行统一配置,或单独自定义组件来导入