Migration vers la v4

Un guide complet pour migrer votre application de Nuxt UI v3 vers Nuxt UI v4.

Nuxt UI v4 marque une étape majeure: **Nuxt UI et Nuxt UI Pro sont désormais unifiés en une seule bibliothèque entièrement open-source et gratuite **. Vous avez désormais accès à plus de 125 composants prêts pour la production, tous disponibles dans le package @nuxt/ui.

Nuxt UI v4 nécessite Nuxt 4.1 ou ultérieure en raison de certaines dépendances. Assurez-vous de mettre à niveau avant de migrer vers Nuxt UI v4.

Ce guide fournit des instructions étape par étape pour migrer votre application de la v3 à la v4.

Migrer votre projet

de Nuxt UI Pro

  1. Remplacer @nuxt/ui-pro par @nuxt/ui dans votre package.json:
pnpm remove @nuxt/ui-pro
pnpm add @nuxt/ui tailwindcss
  1. Remplacer @nuxt/ui-pro par @nuxt/ui dans votre vite.config.ts:
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
- import uiPro from '@nuxt/ui-pro/vite'
+ import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
-   uiPro({
+   ui({
      ui: {
        colors: {
          primary: 'green',
          neutral: 'slate'
        }
      }
    })
  ]
})
  1. Utilisez la clé ui au lieu de uiPro dans votre vite.config.ts:
vite.config.ts
export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        colors: {
          primary: 'green',
          neutral: 'slate'
        },
+       pageCard: {
+         slots: {
+           root: 'rounded-xl',
+         }
+       }
      },
-     uiPro: {
-       pageCard: {
-         slots: {
-           root: 'rounded-xl',
-         }
-       }
-     }
    })
  ]
})
  1. Remplacer @nuxt/ui-pro par @nuxt/ui dans votre CSS:
src/assets/css/main.css
@import "tailwindcss";
- @import "@nuxt/ui-pro";
+ @import "@nuxt/ui";
  1. Remplacer @nuxt/ui-pro par @nuxt/ui dans vos importations:
- import type { BannerProps } from '@nuxt/ui-pro'
+ import type { BannerProps } from '@nuxt/ui'

De l'interface utilisateur Nuxt

  1. Lors de la mise à niveau depuis Nuxt UI v3, il vous suffit de passer à la v4:
pnpm add @nuxt/ui tailwindcss

Changements depuis la v3

Après la mise à niveau vers Nuxt UI v4, veuillez noter les changements importants suivants:

Renommée ButtonGroup

Le composant ButtonGroup a été renommé en FieldGroup:

<template>
- <UButtonGroup>
+ <UFieldGroup>
    <UButton label="Button" />
    <UButton icon="i-lucide-chevron-down" />
+ </UFieldGroup>
- </UButtonGroup>
</template>

Renommée PageMarquee

Le composant PageMarquee a été renommé en Marquee:

<template>
- <UPageMarquee :items="items" />
+ <UMarquee :items="items" />
</template>

PageSupprimé Accordéon

Le composant PageAccordion a été supprimé en faveur du Accordion:

<template>
- <UPageAccordion
+ <UAccordion
    :items="items"
+   :unmount-on-hide="false"
+   :ui="{ trigger: 'text-base', body: 'text-base text-muted' }"
  />
</template>
Le composant PageAccordion était un wrapper qui définissait unmount-on-hide à false et personnalisait le ui prop.

Modificateurs de modèle renommés

La forme modelModifiers utilisée par [Input/docs/components/input), et a changé dans v4:

  1. Le modificateur nullify a été renommé en nullable(il convertit les valeurs vides/vierges en null).
  2. Un nouveau modificateur optional a été ajouté (il convertit les valeurs vides/vides en undefined).
- <UInput v-model.nullify="value" />
+ <UInput v-model.nullable="value" />
- <UTextarea v-model="value" :model-modifiers="{ nullify: true }" />
+ <UTextarea v-model="value" :model-modifiers="{ nullable: true }" />

Utilisez nullable lorsque vous voulez des valeurs vides comme null, et optional lorsque vous préférez undefined pour les valeurs absentes.

Modifications apportées au composant de formulaire

Le composant Form a été amélioré dans la v4 avec une meilleure gestion des états et une gestion des formulaires imbriqués. Voici les principaux changements dont vous devez être conscient:

  1. Schema **transformations ne seront appliquées qu 'aux @submit data et ne modifieront plus l'état de la forme.
  2. **Les formulaires imbriqués doivent être activés explicitement ** en utilisant la prop.nested. Cela rend le comportement du composant plus explicite et empêche la création accidentelle de formulaires imbriqués.
  3. Les formulaires imbriqués devraient maintenant fournir un prop name(similaire à UFormField) et hériteront automatiquement de leur état de leur formulaire parent.
<template>
  <UForm :state="state" :schema="schema" @submit="onSubmit">
    <UFormField label="Customer" name="customer">
      <UInput v-model="state.customer" placeholder="Wonka Industries" />
    </UFormField>

    <div v-for="(item, index) in state.items" :key="index">
      <UForm
-       :state="item"
+       :name="`items.${index}`"
        :schema="itemSchema"
+       nested
      >
        <UFormField :label="!index ? 'Description' : undefined" name="description">
          <UInput v-model="item.description" />
        </UFormField>
        <UFormField :label="!index ? 'Price' : undefined" name="price">
          <UInput v-model="item.price" type="number" />
        </UFormField>
      </UForm>
    </div>
  </UForm>
</template>

Suppression des utilitaires dépréciés

Certaines utilités **Nuxt Content ** qui étaient auparavant disponibles dans Nuxt UI Pro ont été **supprimées ** dans la v4:

@@ @@

Ceux-ci sont désormais entièrement fournis par Nuxt Content. Assurez-vous de mettre à jour vos importations et votre utilisation en conséquence.

- import { findPageHeadline } from '@nuxt/ui-pro/utils/content'
+ import { findPageHeadline } from '@nuxt/content/utils'

- import { findPageBreadcrumb } from '@nuxt/ui-pro/utils/content'
+ import { findPageBreadcrumb } from '@nuxt/content/utils'

AI SDK migration (optionnel)

Cette section s'applique uniquement si vous utilisez le kit de développement intelligent (SDK) et les composants de chat (ChatMessage,ChatMessages,ChatPrompt,ChatPromptSubmit,ChatPalette). Si vous n'utilisez pas les fonctionnalités d'IA, vous pouvez ignorer cette section.

  1. Update @ai-sdk/vue et ai dans vos package.json et ajoutez Comark(remplace @nuxtjs/mdc pour le rendu des réponses AI en tant que Markdown en streaming):
{
  "dependencies": {
-   "@ai-sdk/vue": "^1.2.x",
+   "@ai-sdk/vue": "^4.0.x",
-   "ai": "^4.3.x",
+   "ai": "^7.0.x",
+   "@comark/vue": "latest"
  }
}
  1. L'API composable useChat a changé:input et handleSubmit ont été supprimés en faveur de sendMessage, et messages est maintenant une référence que vous définissez directement:
<script setup lang="ts">
  import { useChat } from '@ai-sdk/vue'

- const { messages, input, handleSubmit, status, error, reload, setMessages } = useChat()
+ const { messages, status, error, sendMessage, regenerate, stop } = useChat()
+ const input = ref('')
+
+ function handleSubmit() {
+   sendMessage({ text: input.value })
+   input.value = ''
+ }
</script>
  1. Messages utilisent maintenant parts au lieu de content:
// When manually creating messages
- setMessages([{
+ messages.value = [{
  id: '1',
  role: 'user',
- content: 'Hello world'
+ parts: [{ type: 'text', text: 'Hello world' }]
- }])
+ }]

// In templates
<template>
- <UChatMessage :content="message.content" />
+ <UChatMessage :parts="message.parts" />
</template>
  1. Quelques méthodes ont été renommées:
// Regenerate the last message
- reload()
+ regenerate()
  1. Remplacer <MDC> par <Markdown> pour le rendu basé sur les pièces. Le composant Markdown est spécialement conçu pour le streaming Markdown, il rend incrémentiellement les jetons à mesure qu 'ils arrivent de l'IA. Utilisez les assistants du SDK AI et l'utilitaire isPartStreaming de @nuxt/ui/utils/ai.
Lorsque vous utilisez le plugin shiki, ajoutez le CSS suivant à votre feuille de style pour la prise en charge du mode sombre:
main.css
html.dark .shiki span {
  color: var(--shiki-dark) !important;
  background-color: var(--shiki-dark-bg) !important;
  font-style: var(--shiki-dark-font-style) !important;
  font-weight: var(--shiki-dark-font-weight) !important;
  text-decoration: var(--shiki-dark-text-decoration) !important;
}
<script setup lang="ts">
import { isReasoningUIPart, isTextUIPart } from 'ai'
import { isPartStreaming } from '@nuxt/ui/utils/ai'
import { Markdown } from '@comark/vue'
import shiki from '@comark/vue/plugins/shiki'

const plugins = [shiki()]
</script>

<template>
  <UChatMessages :messages="messages" :status="status">
    <template #content="{ message }">
      <template v-for="(part, index) in message.parts" :key="`${message.id}-${part.type}-${index}`">
        <UChatReasoning
          v-if="isReasoningUIPart(part)"
          :text="part.text"
          :streaming="isPartStreaming(part)"
        >
          <Markdown
            :value="part.text"
            :streaming="isPartStreaming(part)"
            :plugins="plugins"
            class="*:first:mt-0 *:last:mb-0"
          />
        </UChatReasoning>

        <template v-else-if="isTextUIPart(part)">
          <Markdown
            v-if="message.role === 'assistant'"
            :value="part.text"
            :streaming="isPartStreaming(part)"
            :plugins="plugins"
            class="*:first:mt-0 *:last:mb-0"
          />
          <p v-else-if="message.role === 'user'" class="whitespace-pre-wrap">
            {{ part.text }}
          </p>
        </template>
      </template>
    </template>
  </UChatMessages>
</template>
Pour plus de détails sur les modifications apportées au SDK AI, consultez les guides de migration du SDK AI **official AI SDK.
Consultez toutes les modifications apportées à la mise à niveau du AI SDK v7 PR pour obtenir une référence de migration détaillée.