Skip to content

Vuetify Bridge

If you use Vuetify on top of the Vue adapter, import the bridge from its own subpath:

javascript
import { createVuetifyRule, fieldProps, getVuetifyErrorMessages } from 'json-rest-schema/vuetify'

This split is intentional:

  • json-rest-schema/vue owns schema-aware form orchestration
  • json-rest-schema/vuetify translates those results into Vuetify rules and error-messages
  • the validation rules still live in the schema layer, not in component glue code

Vuetify rules integration

Vuetify's rules prop is a natural fit for path-scoped validation.

javascript
const slugRule = createVuetifyRule(form, 'workspace.slug')

Then bind it to a component:

vue
<v-text-field
  v-model="values.workspace.slug"
  :rules="[slugRule]"
/>

That rule:

  • clones the current form values
  • injects the field's current candidate value at the selected path
  • runs validateField(path, ...)
  • returns either true or the schema error message

So the rule stays a thin bridge. It does not re-implement validation logic.

Vuetify fieldProps() helper

If you want a compact helper for Vuetify inputs, use fieldProps():

javascript
const slugProps = fieldProps(form, 'workspace.slug')

Then:

vue
<v-text-field
  v-model="values.workspace.slug"
  v-bind="slugProps"
/>

By default, fieldProps() returns only a rules array.

That default is deliberate. Vuetify merges error-messages with rule-generated messages, so returning both by default would duplicate the same message on screen.

If you explicitly want manual error-messages too, opt in:

javascript
const slugProps = fieldProps(form, 'workspace.slug', {
  includeErrorMessages: true
})

That adds:

  • errorMessages
  • error

on top of the generated rules.

Manual Vuetify error messages

If you only want the message bridge without generated rules, use getVuetifyErrorMessages() directly:

javascript
const messages = getVuetifyErrorMessages(form, 'workspace.slug')

Then:

vue
<v-text-field
  v-model="values.workspace.slug"
  :error-messages="getVuetifyErrorMessages(form, 'workspace.slug')"
/>

This is useful when:

  • you validate on submit instead of on blur/input
  • you already ran form.validate() or form.validateField()
  • you want Vuetify to display stored schema errors without re-running rules immediately

Worked Vue + Vuetify example

javascript
import { reactive } from 'vue'
import { createSchema } from 'json-rest-schema'
import { useSchemaForm, useSchemaField } from 'json-rest-schema/vue'
import { fieldProps } from 'json-rest-schema/vuetify'

const workspaceSummarySchema = createSchema({
  id: { type: 'id', required: true },
  slug: { type: 'string', required: true, minLength: 3 },
  ownerUserId: { type: 'id', required: true }
})

const workspaceSchema = createSchema({
  workspace: {
    type: 'object',
    required: true,
    schema: workspaceSummarySchema
  }
})

const values = reactive({
  workspace: {
    slug: ''
  }
})

const form = useSchemaForm(workspaceSchema, {
  values,
  operation: 'patch'
})

const slugField = useSchemaField(form, 'workspace.slug')
const slugProps = fieldProps(form, 'workspace.slug')

const saveWorkspace = form.submit(async (validatedObject) => {
  await api.saveWorkspace(validatedObject)
})
vue
<template>
  <v-form @submit.prevent="saveWorkspace">
    <v-text-field
      v-model="values.workspace.slug"
      label="Workspace slug"
      v-bind="slugProps"
      @blur="slugField.validate()"
    />

    <v-btn type="submit">Save</v-btn>
  </v-form>
</template>

That example preserves the intended layering:

  • the schema owns normalization and validation
  • Vue owns local form state
  • Vuetify owns rendering and input UX
  • submit handlers own business logic and API calls

GPL-3.0-only