迁移到 v4

迁移到 v3
一份全面的指南,用于将您的应用程序从 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

  1. 在您的 package.json 中,将 @nuxt/ui-pro 替换为 @nuxt/ui
pnpm remove @nuxt/ui-pro
pnpm add @nuxt/ui
  1. 在您的 nuxt.config.ts 中,将 @nuxt/ui-pro 替换为 @nuxt/ui
nuxt.config.ts
export default defineNuxtConfig({
  modules: [
-   '@nuxt/ui-pro',
+   '@nuxt/ui'
  ]
})
  1. 在您的 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'
        }
      }
    })
  ]
})
  1. 在您的 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',
-     }
-   }
- }
})
  1. 在您的 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',
-         }
-       }
-     }
    })
  ]
})
  1. 在您的 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";
  1. 在您的导入中,将 @nuxt/ui-pro 替换为 @nuxt/ui
- import type { BannerProps } from '@nuxt/ui-pro'
+ import type { BannerProps } from '@nuxt/ui'

从 Nuxt UI

  1. 从 Nuxt UI v3 升级时,您只需更新到 v4
pnpm 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 属性。

模型修饰符已重命名

InputInputNumberTextarea 使用的 modelModifiers 形状在 v4 中已更改

  1. nullify 修饰符已重命名为 nullable(它将空/空白值转换为 null)。
  2. 添加了一个新的 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 中得到了改进,具有更好的状态管理和嵌套表单处理。以下是您需要注意的关键变更

  1. Schema 转换将仅应用于 @submit 数据,并且不再改变表单的状态。这提供了更好的可预测性并防止了意外的状态突变。
  2. 必须使用 nested 属性显式启用嵌套表单。这使得组件行为更加明确,并防止意外创建嵌套表单。
  3. 嵌套表单现在应该提供一个 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 和聊天组件(ChatMessageChatMessagesChatPromptChatPromptSubmitChatPalette)的情况。如果您不使用 AI 功能,可以跳过本节。

  1. 在您的 package.json 中更新 @ai-sdk/vueai 依赖项
{
  "dependencies": {
-   "@ai-sdk/vue": "^1.2.x",
+   "@ai-sdk/vue": "^2.0.x",
-   "ai": "^4.3.x"
+   "ai": "^5.0.x"
  }
}
  1. 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>
  1. 消息现在使用 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>
  1. 一些方法已重命名
// Regenerate the last message
- reload()
+ chat.regenerate()

// Access chat state
- :messages="messages"
- :status="status"
+ :messages="chat.messages"
+ :status="chat.status"
  1. 新增 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>
有关 AI SDK v5 更改的更多详细信息,请查阅官方 AI SDK v5 迁移指南
升级 PR 中查看 AI SDK v4 到 v5 的所有更改,以获取详细的迁移参考。