Vue Form Adapter
If you use Vue, this package now ships a small adapter layer as a separate subpath export:
import { useSchemaForm, useSchemaField } from 'json-rest-schema/vue'That split is intentional.
json-rest-schema/vuehandles schema-aware form orchestration- the core schema engine stays framework-agnostic
Just as important: the adapter does not import Vue internally.
They work with:
- plain objects
- Vue reactive proxies
- Vue refs such as
ref({ ... })
That keeps the published package small and avoids turning Vue into a hard dependency of the core runtime.
Basic Vue usage
Use useSchemaForm() when you already own the form values in Vue state.
import { reactive } from 'vue'
import { createSchema } from 'json-rest-schema'
import { useSchemaForm } from 'json-rest-schema/vue'
const profileSchema = createSchema({
name: { type: 'string', required: true, minLength: 3 },
role: { type: 'string', defaultTo: 'guest' }
})
const values = reactive({
name: ''
})
const form = useSchemaForm(profileSchema, {
values
})If you want Vue to react to adapter-managed error or result updates, pass Vue-owned containers such as ref({}), reactive({}), or ref(null):
import { reactive, ref } from 'vue'
const values = reactive({
name: ''
})
const errors = ref({})
const lastResult = ref(null)
const form = useSchemaForm(profileSchema, {
values,
errors,
lastResult
})That keeps reactivity in the Vue app instead of hiding framework state inside the schema library.
Important behavior:
- full-form validation defaults to
createsemantics form.validate()returns the usual{ validatedObject, errors }form.errorsstays in the library's flat dotted-path formatform.nestedErrorsgives you the nested object/array form if your Vue layer prefers it
Running a full validation:
const result = form.validate()If values is:
{
name: ' Alex '
}then result will be:
{
validatedObject: {
name: 'Alex',
role: 'guest'
},
errors: {}
}That is the same contract as the core schema engine. The Vue adapter does not invent a second validation format.
Field-level validation in Vue
For blur validation, wizard steps, or one-field re-validation, use the path-aware helpers.
const fieldResult = form.validateField('name')
const stepResult = form.validateFields(['name', 'role'])This matters because the adapter validates only the selected paths.
That means:
- validating
namedoes not suddenly produceemailorpassworderrors - nested paths such as
workspace.slugwork the same way as they do in the core APIs - bracket paths such as
roles[0].labelare accepted too
If you want a path-focused helper object, use useSchemaField():
const nameField = useSchemaField(form, 'name')It gives you:
nameField.valuenameField.errornameField.hasErrornameField.messagenameField.messagesnameField.validate()nameField.clearError()
Example:
nameField.validate()
console.log(nameField.messages)Submit normalization in Vue
The clean submit path is:
const submitProfile = form.submit((validatedObject) => {
return api.saveProfile(validatedObject)
})submit() always validates first.
If validation fails:
- the handler is not called
- the returned value is the validation result
form.errorsis updated
If validation succeeds:
- the handler receives the normalized
validatedObject - defaults and casts are already applied
This keeps the same intended split as the rest of the library:
- raw values while the user is typing
- normalized values at the submit boundary
Edit forms and custom operations in Vue
If the form is editing an existing resource, choose a different operation explicitly:
const form = useSchemaForm(profileSchema, {
values,
operation: 'patch'
})You can also use a custom schema operation:
const form = useSchemaForm(profileSchema, {
values,
operation: 'upsert'
})The adapter routes everything back through the schema operation registry, so custom operations behave the same way here as they do in the core runtime.
If you render those forms with Vuetify, use the separate bridge below. It stays thin on purpose and translates the Vue adapter's existing validation results into Vuetify-friendly props and rule callbacks.