Skip to main content
The @jsonforms/vue package provides Vue 3 components for integrating JSON Forms into Vue applications. These components use Vue’s Composition API and provide/inject pattern for state management.

JsonForms

The main component for rendering a complete JSON Form. This is the root component that provides form state to all child components.
import { JsonForms } from '@jsonforms/vue';

Props

data
any
The data to be rendered by the form. Can be any JSON-compatible type (object, array, string, number, boolean).
schema
JsonSchema
The JSON Schema describing the data structure and validation rules. If not provided, a schema will be generated from the data.
uischema
UISchemaElement
The UI Schema defining how the form should be rendered. If not provided, a default UI schema will be generated from the JSON Schema.
renderers
JsonFormsRendererRegistryEntry[]
required
Array of renderer registrations that define which components handle which UI schema elements. This is required.
cells
JsonFormsCellRendererRegistryEntry[]
default:"[]"
Array of cell renderer registrations for rendering controls in compact mode (e.g., within tables).
config
any
Global configuration object that can be accessed by all renderers.
readonly
boolean
default:"false"
When true, all form controls will be rendered in read-only mode.
uischemas
JsonFormsUISchemaRegistryEntry[]
default:"[]"
Array of UI schema registrations for dynamic schema resolution.
validationMode
ValidationMode
default:"'ValidateAndShow'"
Controls when validation errors are displayed. Options:
  • 'ValidateAndShow': Validate and show errors
  • 'ValidateAndHide': Validate but don’t show errors
  • 'NoValidation': Don’t validate
ajv
Ajv
Custom AJV instance for validation. If not provided, a default instance will be created.
i18n
JsonFormsI18nState
Internationalization configuration including locale, translate function, and error translation.
additionalErrors
ErrorObject[]
default:"[]"
Additional validation errors to display alongside schema validation errors.
middleware
Middleware
default:"defaultMiddleware"
Custom middleware function for intercepting and modifying core state updates.

Events

@change
JsonFormsChangeEvent
Emitted when the form data or validation errors change.Event structure:
{
  data: any;           // Updated form data
  errors: ErrorObject[]; // Current validation errors
}

Example

<template>
  <json-forms
    :data="formData"
    :schema="schema"
    :uischema="uischema"
    :renderers="renderers"
    @change="onChange"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { JsonForms } from '@jsonforms/vue';
import { vanillaRenderers } from '@jsonforms/vue-vanilla';

const renderers = vanillaRenderers;

const schema = {
  type: 'object',
  properties: {
    name: {
      type: 'string',
      minLength: 3
    },
    email: {
      type: 'string',
      format: 'email'
    },
    age: {
      type: 'number',
      minimum: 0,
      maximum: 120
    }
  },
  required: ['name', 'email']
};

const uischema = {
  type: 'VerticalLayout',
  elements: [
    {
      type: 'Control',
      scope: '#/properties/name'
    },
    {
      type: 'Control',
      scope: '#/properties/email'
    },
    {
      type: 'Control',
      scope: '#/properties/age'
    }
  ]
};

const formData = ref({});

const onChange = (event: any) => {
  console.log('Data:', event.data);
  console.log('Errors:', event.errors);
  formData.value = event.data;
};
</script>

DispatchRenderer

Internal component that dispatches rendering to the appropriate registered renderer based on the UI schema element. This component selects the best matching renderer using tester functions.
import { DispatchRenderer } from '@jsonforms/vue';

Props

Accepts all renderer props via rendererProps():
schema
JsonSchema
required
The JSON Schema for the current element.
uischema
UISchemaElement
required
The UI Schema element to render.
path
string
required
The data path to the current element.
enabled
boolean
Whether the element is enabled.
renderers
JsonFormsRendererRegistryEntry[]
Optional override for the renderer registry.
cells
JsonFormsCellRendererRegistryEntry[]
Optional override for the cell registry.
config
any
Optional override for the configuration.

Usage

<template>
  <dispatch-renderer
    :schema="schema"
    :uischema="uischema"
    :path="path"
  />
</template>

DispatchCell

Internal component for dispatching cell rendering. Similar to DispatchRenderer but specifically for cells, which are compact control renderers typically used in tables.
import { DispatchCell } from '@jsonforms/vue';

Props

Accepts the same props as DispatchRenderer but with ControlElement type for uischema:
uischema
ControlElement
required
The control UI Schema element to render as a cell.

Usage

<template>
  <dispatch-cell
    :schema="schema"
    :uischema="controlUischema"
    :path="path"
  />
</template>

UnknownRenderer

Fallback component displayed when no suitable renderer is found for a UI schema element.
import { UnknownRenderer } from '@jsonforms/vue';
This component displays the message: “No applicable renderer found.”

Template

<template>
  <div>No applicable renderer found.</div>
</template>

Creating Custom Renderers

To create custom renderers for Vue, you can use the composables provided by the package. Here’s an example:
<template>
  <div v-if="control.visible" class="my-custom-control">
    <label>{{ control.label }}</label>
    <input
      :value="control.data"
      :disabled="!control.enabled"
      @input="onChange($event.target.value)"
    />
    <div v-if="control.errors" class="error">
      {{ control.errors }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { rendererProps, useJsonFormsControl } from '@jsonforms/vue';

const props = defineProps({
  ...rendererProps<ControlElement>()
});

const { control, handleChange } = useJsonFormsControl(props);

const onChange = (value: string) => {
  handleChange(control.value.path, value);
};
</script>
Then register your custom renderer:
import { rankWith, isStringControl } from '@jsonforms/core';
import MyCustomControl from './MyCustomControl.vue';

const myCustomControlRenderer = {
  renderer: MyCustomControl,
  tester: rankWith(3, isStringControl)
};

const renderers = [
  ...vanillaRenderers,
  myCustomControlRenderer
];

Provide/Inject Pattern

The JsonForms component provides the following values to all descendant components:
  • jsonforms: The complete JSON Forms state (JsonFormsSubStates)
  • dispatch: Function to dispatch core actions
You can access these in custom components:
<script setup lang="ts">
import { inject } from 'vue';
import { JsonFormsSubStates, Dispatch, CoreActions } from '@jsonforms/core';

const jsonforms = inject<JsonFormsSubStates>('jsonforms');
const dispatch = inject<Dispatch<CoreActions>>('dispatch');

if (!jsonforms || !dispatch) {
  throw new Error('Must be used within JsonForms component');
}

console.log('Current data:', jsonforms.core.data);
console.log('Current schema:', jsonforms.core.schema);
</script>
All custom renderers must be used within a JsonForms component to have access to the form state via Vue’s provide/inject.

Build docs developers (and LLMs) love