Skip to content

Utiliser FormViewer

FormViewer exécute un schéma généré par FormBuilder.

Il est utile pour :

  • afficher un formulaire à un utilisateur final ;
  • prévisualiser un formulaire sauvegardé ;
  • intégrer un formulaire dynamique dans un portail métier ;
  • rejouer un formulaire stocké dans MongoDB, Feathers/NFZ ou une autre API.

Contrat minimal

vue
<FormViewer
  v-model="values"
  :form-fields="schema"
  @submit="handleSubmit"
/>

form-fields correspond au schéma FormKit/Quasar généré par le builder.

Exemple complet

vue
<script setup lang="ts">
import type { FormKitSchemaDefinition } from '@formkit/core'

type FormSchema = FormKitSchemaDefinition[]
type FormValues = Record<string, unknown>

const schema = ref<FormSchema>([
  {
    $formkit: 'q-input',
    name: 'firstname',
    label: 'Prénom',
    inputType: 'text',
    validation: 'required',
  },
  {
    $formkit: 'q-input',
    name: 'email',
    label: 'Adresse e-mail',
    inputType: 'email',
    validation: 'required|email',
  },
  {
    $formkit: 'q-btn',
    name: 'submit',
    buttonLabel: 'Envoyer',
    type: 'submit',
    color: 'primary',
    ignore: true,
  },
])

const values = ref<FormValues>({})

function handleSubmit(data: FormValues) {
  console.log('Formulaire soumis', data)
}
</script>

<template>
  <QPage padding>
    <QCard flat bordered class="q-pa-lg">
      <FormViewer
        v-model="values"
        :form-fields="schema"
        @submit="handleSubmit"
      />
    </QCard>
  </QPage>
</template>

Mode lecture seule

vue
<template>
  <FormViewer
    v-model="values"
    :form-fields="schema"
    readonly
  />
</template>

En mode readonly, le composant bloque la modification des valeurs et ignore la soumission.

Charger un schéma depuis une API

vue
<script setup lang="ts">
import type { FormKitSchemaDefinition } from '@formkit/core'

type FormDocument = {
  id: string
  schema: FormKitSchemaDefinition[]
}

type FormValues = Record<string, unknown>

const route = useRoute()
const values = ref<FormValues>({})

const { data, pending, error } = await useAsyncData<FormDocument>(
  () => `form-document-${route.params.id}`,
  async () => {
    return await $fetch<FormDocument>(`/api/forms/${route.params.id}`)
  },
)

const schema = computed(() => data.value?.schema || [])

function handleSubmit(payload: FormValues) {
  return $fetch(`/api/forms/${route.params.id}/submissions`, {
    method: 'POST',
    body: payload,
  })
}
</script>

<template>
  <QPage padding>
    <QBanner v-if="error" class="bg-negative text-white">
      Impossible de charger le formulaire.
    </QBanner>

    <QInnerLoading :showing="pending" />

    <FormViewer
      v-if="!pending"
      v-model="values"
      :form-fields="schema"
      @submit="handleSubmit"
    />
  </QPage>
</template>

Bonne pratique

Ne fais pas confiance au schéma côté client si le formulaire déclenche une action sensible. Valide toujours les données reçues côté serveur avec Zod, Valibot, Yup, ou des validators Feathers/NFZ.

QForm Builder — couche Nuxt 4 / Quasar / FormKit réutilisable.