Migration vers la 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.
Ce guide fournit des instructions étape par étape pour migrer votre application de la v3 à la v4.
Migrer votre projet
de Nuxt UI Pro
- Remplacer
@nuxt/ui-propar@nuxt/uidans votrepackage.json:
pnpm remove @nuxt/ui-pro
pnpm add @nuxt/ui tailwindcss
yarn remove @nuxt/ui-pro
yarn add @nuxt/ui tailwindcss
npm uninstall @nuxt/ui-pro
npm install @nuxt/ui tailwindcss
bun remove @nuxt/ui-pro
bun add @nuxt/ui tailwindcss
- Remplacer
@nuxt/ui-propar@nuxt/uidans votrevite.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'
}
}
})
]
})
- Utilisez la clé
uiau lieu deuiProdans votrevite.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',
- }
- }
- }
})
]
})
- Remplacer
@nuxt/ui-propar@nuxt/uidans votre CSS:
@import "tailwindcss";
- @import "@nuxt/ui-pro";
+ @import "@nuxt/ui";
- Remplacer
@nuxt/ui-propar@nuxt/uidans vos importations:
- import type { BannerProps } from '@nuxt/ui-pro'
+ import type { BannerProps } from '@nuxt/ui'
De l'interface utilisateur Nuxt
- Lors de la mise à niveau depuis Nuxt UI v3, il vous suffit de passer à la v4:
pnpm add @nuxt/ui tailwindcss
yarn add @nuxt/ui tailwindcss
npm install @nuxt/ui tailwindcss
bun 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>
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:
- Le modificateur
nullifya été renommé ennullable(il convertit les valeurs vides/vierges ennull). - Un nouveau modificateur
optionala été ajouté (il convertit les valeurs vides/vides enundefined).
- <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:
- Schema **transformations ne seront appliquées qu 'aux
@submitdata et ne modifieront plus l'état de la forme. - **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. - 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.
- Update
@ai-sdk/vueetaidans vospackage.jsonet ajoutez Comark(remplace@nuxtjs/mdcpour 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"
}
}
- L'API composable
useChata changé:inputethandleSubmitont été supprimés en faveur desendMessage, etmessagesest 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>
- Messages utilisent maintenant
partsau lieu decontent:
// 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>
- Quelques méthodes ont été renommées:
// Regenerate the last message
- reload()
+ regenerate()
- Remplacer
<MDC>par<Markdown>pour le rendu basé sur les pièces. Le composantMarkdownest 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'utilitaireisPartStreamingde@nuxt/ui/utils/ai.
shiki, ajoutez le CSS suivant à votre feuille de style pour la prise en charge du mode sombre: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>