迁移到 v4
一份全面的指南,用于将您的应用程序从 Nuxt UI v3 迁移到 Nuxt UI v4。
Nuxt UI v4 标志着一个重要的里程碑:Nuxt UI 和 Nuxt UI Pro 现已统一到一个完全开源且免费的库中。您现在可以访问 100 多个生产就绪组件,所有这些组件都可在 @nuxt/ui
包中找到。
Nuxt UI v4 由于一些依赖关系,需要 Nuxt 4。在迁移到 Nuxt UI v4 之前,请务必升级到 Nuxt 4。
本指南提供了将您的应用程序从 v3 迁移到 v4 的分步说明。
迁移您的项目
从 Nuxt UI Pro
- 在您的
package.json
中,将@nuxt/ui-pro
替换为@nuxt/ui
pnpm remove @nuxt/ui-pro
pnpm add @nuxt/ui
yarn remove @nuxt/ui-pro
yarn add @nuxt/ui
npm uninstall @nuxt/ui-pro
npm install @nuxt/ui
bun remove @nuxt/ui-pro
bun add @nuxt/ui
- 在您的
nuxt.config.ts
中,将@nuxt/ui-pro
替换为@nuxt/ui
nuxt.config.ts
export default defineNuxtConfig({
modules: [
- '@nuxt/ui-pro',
+ '@nuxt/ui'
]
})
- 在您的
vite.config.ts
中,将@nuxt/ui-pro
替换为@nuxt/ui
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'
}
}
})
]
})
- 在您的
app.config.ts
中,使用ui
键而不是uiPro
app.config.ts
export default defineAppConfig({
ui: {
colors: {
primary: 'green',
neutral: 'slate'
},
+ pageCard: {
+ slots: {
+ root: 'rounded-xl',
+ }
+ }
},
- uiPro: {
- pageCard: {
- slots: {
- root: 'rounded-xl',
- }
- }
- }
})
- 在您的
vite.config.ts
中,使用ui
键而不是uiPro
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',
- }
- }
- }
})
]
})
- 在您的 CSS 中,将
@nuxt/ui-pro
替换为@nuxt/ui
app/assets/css/main.css
@import "tailwindcss";
- @import "@nuxt/ui-pro";
+ @import "@nuxt/ui";
如果您在升级 Nuxt UI v4 的同时升级到 Nuxt 4,请确保更新
@source
指令以匹配新的目录结构。app/assets/css/main.css
@import "tailwindcss";
@import "@nuxt/ui";
- @source "../../content/**/*";
+ @source "../../../content/**/*";
src/assets/css/main.css
@import "tailwindcss";
- @import "@nuxt/ui-pro";
+ @import "@nuxt/ui";
- 在您的导入中,将
@nuxt/ui-pro
替换为@nuxt/ui
- import type { BannerProps } from '@nuxt/ui-pro'
+ import type { BannerProps } from '@nuxt/ui'
从 Nuxt UI
- 从 Nuxt UI v3 升级时,您只需更新到 v4
pnpm add @nuxt/ui
yarn add @nuxt/ui
npm install @nuxt/ui
bun add @nuxt/ui
v3 的变更
升级到 Nuxt UI v4 后,请注意以下重要变更
ButtonGroup 已重命名
ButtonGroup
组件已重命名为 FieldGroup
<template>
- <UButtonGroup>
+ <UFieldGroup>
<UButton label="Button" />
<UButton icon="i-lucide-chevron-down" />
+ </UFieldGroup>
- </UButtonGroup>
</template>
PageMarquee 已重命名
PageMarquee
组件已重命名为 Marquee
<template>
- <UPageMarquee :items="items" />
+ <UMarquee :items="items" />
</template>
PageAccordion 已移除
PageAccordion
组件已移除,取而代之的是 Accordion
<template>
- <UPageAccordion
+ <UAccordion
:items="items"
+ :unmount-on-hide="false"
+ :ui="{ trigger: 'text-base', body: 'text-base text-muted' }"
/>
</template>
PageAccordion
组件是一个包装器,它将 unmount-on-hide
设置为 false
并自定义了 ui
属性。模型修饰符已重命名
由 Input
、InputNumber
和 Textarea
使用的 modelModifiers
形状在 v4 中已更改
nullify
修饰符已重命名为nullable
(它将空/空白值转换为null
)。- 添加了一个新的
optional
修饰符(它将空/空白值转换为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 }" />
当您希望空值为 null
时,请使用 nullable
;当您更喜欢 undefined
表示缺失值时,请使用 optional
。
Form 组件的变更
Form
组件在 v4 中得到了改进,具有更好的状态管理和嵌套表单处理。以下是您需要注意的关键变更
- Schema 转换将仅应用于
@submit
数据,并且不再改变表单的状态。这提供了更好的可预测性并防止了意外的状态突变。 - 必须使用
nested
属性显式启用嵌套表单。这使得组件行为更加明确,并防止意外创建嵌套表单。 - 嵌套表单现在应该提供一个
name
属性(类似于UFormField
),并将自动从其父表单继承状态。
<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>
移除了已弃用的工具
Nuxt UI Pro 中以前可用的一些 Nuxt Content 工具在 v4 中已移除
findPageBreadcrumb
findPageHeadline
这些现在完全由 Nuxt Content 提供。请务必相应地更新您的导入和用法。
- 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 v5 迁移(可选)
本节仅适用于您使用 AI SDK 和聊天组件(ChatMessage
、ChatMessages
、ChatPrompt
、ChatPromptSubmit
、ChatPalette
)的情况。如果您不使用 AI 功能,可以跳过本节。
- 在您的
package.json
中更新@ai-sdk/vue
和ai
依赖项
{
"dependencies": {
- "@ai-sdk/vue": "^1.2.x",
+ "@ai-sdk/vue": "^2.0.x",
- "ai": "^4.3.x"
+ "ai": "^5.0.x"
}
}
useChat
可组合函数已替换为新的Chat
类
<script setup lang="ts">
- import { useChat } from '@ai-sdk/vue'
+ import { Chat } from '@ai-sdk/vue'
+ import type { UIMessage } from 'ai'
- const { messages, input, handleSubmit, status, error, reload, setMessages } = useChat()
+ const messages: UIMessage[] = []
+ const input = ref('')
+
+ const chat = new Chat({
+ messages
+ })
+
+ function handleSubmit(e: Event) {
+ e.preventDefault()
+ chat.sendMessage({ text: input.value })
+ input.value = ''
+ }
</script>
- 消息现在使用
parts
而不是content
// When manually creating messages
- setMessages([{
+ messages.push({
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>
- 一些方法已重命名
// Regenerate the last message
- reload()
+ chat.regenerate()
// Access chat state
- :messages="messages"
- :status="status"
+ :messages="chat.messages"
+ :status="chat.status"
- 新增
getTextFromMessage
工具,用于从 AI SDK v5 消息部分中提取文本
<script setup lang="ts">
import { getTextFromMessage } from '@nuxt/ui/utils/ai'
</script>
<template>
<UChatMessages :messages="chat.messages" :status="chat.status">
<template #content="{ message }">
<!-- Extract text from message parts and render with MDC -->
<MDC :value="getTextFromMessage(message)" :cache-key="message.id" unwrap="p" />
</template>
</UChatMessages>
</template>