Quick Start
@formily/json-schema is the protocol layer behind Formily's JSON Schema development mode. The official docs describe three approaches to building forms: Markup Schema, JSON Schema, and JSX Components. Both Markup Schema and JSON Schema rely on the capabilities provided by @formily/json-schema. @formily/json-schema uses a plain object to describe form structure, component mapping, and linkage logic, which makes recursive rendering possible.
In simple terms, different packages are responsible for different parts:
@formily/coremanages the form instance, field state, validation, and effects@formily/json-schemadefines the schema protocol, expression compilation, andSchemaclass APIs- front-end binding libraries such as
@silver-formily/vue,@formily/vue, and@silver-formily/reactrecursively render the schema into a component tree
Note
The official Formily examples use @formily/vue. This rewritten documentation uses @silver-formily/vue. There is no capability gap between them, and the APIs are broadly similar. For the detailed differences, see the related documentation at vue.silver-formily.org.
Why Rewrite This
The official documentation is fairly rough in several places, leaves some behavior unexplained, and is not particularly pleasant to navigate. This documentation site is a structured rewrite of the official content, with runnable examples and better searchability.
Installation
pnpm add @silver-formily/vue @formily/core @formily/json-schema @formily/reactive @silver-formily/reactive-vue @formily/shared@formily/json-schema does not render UI by itself. To turn a schema into an actual Vue form, you still need @formily/core and @silver-formily/vue or another front-end binding library.
Minimal Example
A minimal setup usually has 4 steps:
- Create a form instance with
createForm() - Register the components used in the schema with
createSchemaField() - Declare a
schemawithtype,properties, andx-component - Render everything with
FormProviderandSchemaField
<script setup lang="ts">
import { createForm } from '@formily/core'
import { createSchemaField, FormConsumer, FormProvider } from '@silver-formily/vue'
import { InputBox, TextAreaBox } from './shared'
const { SchemaField } = createSchemaField({
components: {
InputBox,
TextAreaBox,
},
})
const schema = {
type: 'object',
properties: {
nickname: {
'type': 'string',
'title': 'Nickname',
'required': true,
'x-component': 'InputBox',
'x-component-props': {
placeholder: 'For example: Silver',
},
},
bio: {
'type': 'string',
'title': 'Bio',
'x-component': 'TextAreaBox',
'x-component-props': {
rows: 4,
placeholder: 'Write a short introduction',
},
},
},
}
const form = createForm({
values: {
nickname: 'Silver',
bio: 'Hello Formily',
},
})
</script>
<template>
<FormProvider :form="form">
<SchemaField :schema="schema" />
<FormConsumer>
<template #default="{ form: currentForm }">
<pre style="margin-top: 10px; white-space: pre-wrap;">{{ JSON.stringify(currentForm.values, null, 2) }}</pre>
</template>
</FormConsumer>
</FormProvider>
</template>{
"nickname": "Silver",
"bio": "Hello Formily"
}Key points from the example:
createSchemaField({ components })defines which component names are available inx-componentschema.properties.nicknameandschema.properties.biodescribe two fieldsx-component-propsis passed directly to the target componentFormConsumeris only used here to preview current values; in real code you can replace it with submit, validation, or linkage logic