ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Formily Vue 中 SchemaField 的 JSON Schema 模式:直接传入 Schema 对象动态渲染表单

2026/9/24 15:33:23 拓冰建站 浏览量
Formily Vue 中 SchemaField 的 JSON Schema 模式:直接传入 Schema 对象动态渲染表单 前端UI组件【免费下载链接】formily Cross Device High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/React Native/Vue 2/Vue 3项目地址https://gitcode.com/gh_mirrors/fo/formily点击查看免费下载导读本文聚焦 formily/vue 协议驱动体系中SchemaField组件的JSON Schema 模式——即不借助 JSX/模板标记而是直接向SchemaField传入一份遵循 JSON-Schema 规范的普通对象来渲染表单。你将掌握createSchemaField工厂函数的用法、x-component等协议字段的语义、表达式作用域与联动协议的书写方式以及 Schema 对象从 JSON 到字段模型的转换原理从而在 Vue 2/Vue 3 项目中实现一份 JSON 驱动整张表单的纯配置化开发。SchemaField 的两种使用模式在 formily/vue 中SchemaField组件是专门用于解析 JSON-Schema 动态渲染表单的组件它存在两种等价的使用形态Markup Schema 模式在SchemaField内部嵌套SchemaStringField、SchemaObjectField等标记组件以模板写协议的方式声明 Schema详见 schema-field.md。JSON Schema 模式不写任何子节点直接将一份 JSON-Schema 对象通过schema属性传入组件。这是本文的主题也是最契合后端下发配置 / 动态渲染场景的用法。两种模式最终都会收敛到同一棵 Schema 树由SchemaField内部统一交给RecursionField递归渲染因此它们表达的协议能力完全一致区别只在于 Schema 的来源模板标记 vs 纯 JSON 数据。快速上手直接传入 Schema 对象官方文档给出的用例schema-field-with-schema.vue是最精简的入门示例template FormProvider :formform SchemaField :schema{ type: object, properties: { input: { type: string, x-component: Input, }, }, } /SchemaField /FormProvider /template script import { Input } from ant-design-vue import { createForm } from formily/core import { FormProvider, createSchemaField } from formily/vue import ant-design-vue/dist/antd.css const { SchemaField } createSchemaField({ components: { Input, }, }) export default { components: { FormProvider, SchemaField }, data() { return { form: createForm(), } }, } /script这个示例完整展示了 JSON Schema 模式的三要素createForm()来自 formily/core创建一个表单核心实例通过FormProvider注入组件树createSchemaField({ components })工厂函数注册可供 Schema 协议引用的组件集合:schema...json...一份纯 JSON 数据其中x-component: Input声明字段使用注册表中的Input组件。运行后页面上会出现一个受 Formily 表单模型管理的输入框其值、校验、联动等全部由 JSON 协议驱动模板中无需再写任何表单状态管理代码。createSchemaField 工厂函数与组件注册所有SchemaField变体都必须经由createSchemaField工厂函数创建源码。其签名定义如下摘自 schema-field.mdtype ComposeSchemaField { SchemaField: Vue.Componentany, any, any, ISchemaFieldProps SchemaMarkupField: Vue.Componentany, any, any, ISchema SchemaStringField: Vue.Componentany, any, any, OmitISchema, type SchemaObjectField: Vue.Componentany, any, any, OmitISchema, type SchemaArrayField: Vue.Componentany, any, any, OmitISchema, type SchemaBooleanField: Vue.Componentany, any, any, OmitISchema, type SchemaDateField: Vue.Componentany, any, any, OmitISchema, type SchemaDateTimeField: Vue.Componentany, any, any, OmitISchema, type SchemaVoidField: Vue.Componentany, any, any, OmitISchema, type SchemaNumberField: Vue.Componentany, any, any, OmitISchema, type } // 工厂函数参数属性 interface ISchemaFieldFactoryProps { components?: { [key: string]: Vue.Component // 组件列表 } scope?: any // 全局作用域用于实现协议表达式变量注入 } // SchemaField 属性 interface ISchemaFieldProps extends IFieldFactoryProps { schema?: ISchema // 字段 schema scope?: any // 协议表达式作用域 name?: string // 字段名称 } // 工厂函数 interface createSchemaField { (props: ISchemaFieldFactoryProps): ComposeSchemaField }需要注意的关键点components是协议与组件之间的翻译表x-component: Input中的字符串Input会去components集合中按 Key 查找对应组件x-decorator同理两者都必须与createSchemaField传入的组件集合的 Key 精确匹配见 schema.md 详细说明。scope用于注入表达式变量工厂函数级scope与组件级scope会被合并lazyMerge供协议中的{{expression}}表达式消费。在源码中这个合并结果通过SchemaExpressionScopeSymbol向下 provideSchemaField.ts。除SchemaField外工厂还会返回 9 个标记组件其中SchemaMarkupField是通用标记其余为按类型string/object/array/boolean/date/datetime/void/number拆分的便捷标记它们仅服务于 Markup 模式。在SchemaField的 props 中schema若是Schema实例则直接复用否则会被包装为new Schema({ type: object, ...props.schema })——这意味着不传type时默认按object处理且 JSON 会被立即转换成带方法的 Schema 树。Schema 协议一份 JSON 能描述什么JSON Schema 模式的核心价值在于Schema 对象的每个字段都会映射到 Formily 的字段模型上。下表整理了完整映射关系摘自 schema.md是书写协议时的字典属性描述类型字段模型映射type类型string \| object \| array \| number \| boolean \| void \| date \| datetimeGeneralFieldtitle标题stringtitledescription描述stringdescriptiondefault默认值anyinitialValuereadOnly是否只读booleanreadOnlywriteOnly是否只写booleaneditableenum枚举SchemaEnumdataSourceconst / multipleOf / maximum / minimum / maxLength / minLength / pattern / maxItems / minItems / uniqueItems / maxProperties / minProperties / required / format校验规则number \| string \| booleanvalidatorproperties对象属性描述Recordstring, ISchema-items数组项描述ISchema \| ISchema[]-additionalItems / patternProperties / additionalProperties扩展描述Schema-x-indexUI 展示顺序number-x-patternUI 交互模式FieldPatternTypespatternx-displayUI 展示FieldDisplayTypesdisplayx-validator字段校验器FieldValidatorvalidatorx-decorator字段 UI 包装器组件string \| 组件decoratorx-decorator-props包装器组件属性anydecoratorx-component字段 UI 组件string \| 组件componentx-component-propsUI 组件属性anycomponentx-reactions字段联动协议SchemaReactionsreactionsx-content字段内容子节点anyReactChildrenx-visible / x-hidden / x-disabled / x-editable / x-read-only / x-read-pretty展示与交互状态booleanvisible / hidden / disabled / editable / readOnly / readPrettydefinitionsSchema 预定义Recordstring, ISchema-$ref引用预定义并合并string-x-data扩展属性objectdata在 JSON Schema 模式下这份表格中除title、default、required、enum等标准 JSON-Schema 关键字可直接使用外所有x-开头的 Formily 扩展字段也都原样可用。因此直接传 JSON并不意味着能力缩水——动态渲染一个带校验、带枚举、带装饰器的完整字段可以写成{ type: object, properties: { name: { type: string, title: 姓名, required: true, x-decorator: FormItem, x-decorator-props: { labelCol: 6, wrapperCol: 10 }, x-component: Input, x-component-props: { placeholder: 请输入姓名 }, x-validator: { minLength: 2 } } } }表达式让 JSON 活起来的{{ }}语法Schema 的每个属性都可以使用字符串表达式约定为以{{开头、}}结尾的字符串即视为表达式片段。表达式变量可以从createSchemaField的scope传入也可以从SchemaField组件的scope传入schema.md 详细说明。例如让默认值来自外部作用域变量SchemaField :scope{ userName: 张三 } :schema{ type: object, properties: { name: { type: string, x-component: Input, default: {{userName}} }, }, } /在 formily/json-schema 的编译实现中Schema实例的compile(scope)方法会深度递归整棵 Schema 树找出所有表达式片段并消费作用域变量Schema.compile静态方法、shallowCompile浅层编译变体以及Schema.silent静默编译开关均有对应实现见 schema.md 方法章节。内置表达式作用域表达式中可直接消费以下内置变量详见 schema.md 内置表达式作用域$self当前字段实例普通属性表达式与x-reactions中均可用$values顶层表单数据$form当前 Form 实例$observable创建响应式对象用法同observable$memo创建持久引用数据用法同autorun.memo$effect响应 autorun 首次执行的下一个微任务时机及 dispose用法同autorun.effect$dependencies/$deps只能在x-reactions表达式中消费与dependencies声明按数组顺序对应$target只能在x-reactions表达式中消费代表主动联动模式下的 target 字段。x-reactionsJSON 中的联动协议x-reactions是 Schema 中最核心的联动协议同样支持主动联动与被动联动两种模式完整定义见 schema.md SchemaReactions主动模式声明target字段路径配合when/fulfill/otherwise控制目标字段的状态或 Schematarget支持 FormPathPattern 匹配路径语法不支持相对路径也可通过effects指定独立生命周期钩子onFieldInit、onFieldMount、onFieldValueChange、onFieldValidateEnd等十余种被动模式声明dependencies依赖字段列表条件满足时更新自身依赖可以是字符串数组取依赖字段的 value、对象数组可用name起别名、property指定依赖属性如source#modified写法或对象格式。一个典型的被动联动示例——当输入框内容为123时展示提示文字{ type: object, properties: { source: { type: string, x-component: Input }, target: { type: string, x-component: Input, x-reactions: { dependencies: [source], fulfill: { schema: { x-visible: {{$deps[0] 123}} } } } } } }x-reactions还支持数组、函数形式x-reactions: {{myReaction}}由作用域注入外部响应器函数实现复杂联动、fulfill.run直接执行$form.setFieldState(...)语句以及通过带路径的 Key 精确操作组件属性如component[1].style.color等写法详见 schema.md 联动用例。源码视角JSON 是如何变成字段的在 RecursionField.ts 中可以看到 JSON Schema 模式的完整执行链Schema 实例化new Schema(schemaProp)将普通 JSON 包装为 Schema 树markRaw包装避免 Vue 过度响应化协议到字段属性schema.toFieldProps({ ...options, scope })将 Schema 节点映射为字段工厂属性映射关系即上文属性表实现于 formily/json-schema 的 schema.ts按 type 分发object/array/void分别渲染ObjectField/ArrayField/VoidField其余类型渲染通用Field递归渲染通过Schema.getOrderProperties按x-index排序后遍历properties对每个子节点再次创建RecursionField完成递归mapProperties/filterProperties可在遍历时改写或过滤子 SchemaonlyRenderProperties控制只渲染子级x-slot则决定子节点落入哪个插槽。在SchemaField组件内部SchemaField.ts传入的schema若已是Schema实例则直接复用否则按type: object包装随后把合并后的组件集合、表达式作用域通过provide注入最终将 props 连同 schema 一并交给RecursionField。也就是说JSON Schema 模式与 Markup Schema 模式最终走的是同一条RecursionField渲染管线这也保证了两种模式渲染结果的一致性。此外Schema 类还提供了一套可编程 API见 schema.md 方法章节在 JSON Schema 模式之外也可以手动使用结构操作addProperty/removeProperty/setProperties/setItems/addPatternProperty等用于动态增删改 Schema 节点遍历与转换mapProperties/reduceProperties均按x-index顺序、fromJSON/toJSON协议兼容registerPatches/registerPolyfills/enablePolyfills([1.0])可注册协议补丁兼容 formily 1.x 的x-props、x-linkages、x-rules等旧写法registerVoidComponents/registerTypeDefaultComponents可声明虚拟组件与类型默认组件。实战建议与局限适合配置驱动场景当表单结构来自接口返回、低代码平台配置或后端动态下发时JSON Schema 模式是最佳选择——模板中只有一行SchemaField :schemaschema /后续增删字段、调整校验与联动全部在 JSON 层完成组件注册是前提x-component/x-decorator引用的每个 Key 都必须在createSchemaField({ components })中注册否则字段无法渲染这是最常见的报错来源$ref仅支持本地定义$ref指定的预定义格式必须形如#/definitions/address不支持加载远程 JSON Schemaschema.md 详细说明表达式有编译边界字符串表达式不能包含复杂语句复杂逻辑应放入作用域注入的函数中如x-reactions的函数形式或fulfill.run语句嵌套结构照常工作properties嵌套 object、items定义数组可配合ArrayTable等数组组件、void类型用于纯布局节点RecursionField会逐层递归处理无需额外模板。如需进一步对比 Markup Schema 的写法、了解ISchema的完整类型定义可继续阅读 schema-field.md 与 schema.md并参考同目录下的 recursion-field.vue 用例演示了RecursionField在自定义组件中手动递归渲染 Schema 的进阶用法。赞分享前端UI组件【免费下载链接】formily Cross Device High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/React Native/Vue 2/Vue 3项目地址https://gitcode.com/gh_mirrors/fo/formily点击查看免费下载相关推荐Formily SchemaField 组件详解JSON Schema 动态表单渲染的完整实战指南Formily SchemaField 组件详解JSON Schema 动态表单渲染的完整实战指南 导读 SchemaField 是 Formily Reac前端UI组件Formily 动态表单核心组件 SchemaField 完全指南Markup Schema 与 JSON Schema 双模式实战Formily 动态表单核心组件 SchemaField 完全指南Markup Schema 与 JSON Schema 双模式实战 SchemaField前端UI组件Formily动态表单引擎JSON Schema极速开发Formily动态表单引擎JSON Schema极速开发 你是否还在为前后端表单数据对接而烦恼是否因频繁修改表单结构导致大量重复编码本文将带你掌握Form前端UI组件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考