迁移
从 Nuxt UI v2 迁移到 Nuxt UI v3 的全面指南。
Nuxt UI v3.0 是一个全新的主版本,从头开始重写,引入了现代架构,显著提升了性能并增强了开发者体验。此主要版本包含了一些重大更改,同时也带来了强大的新特性和功能。
- Tailwind CSS v4:从基于 JavaScript 的配置迁移到基于 CSS 的配置
- Reka UI:取代 Headless UI 成为底层组件库
- Tailwind Variants:用于组件变体的新样式 API
本指南提供了将应用从 v2 迁移到 v3 的分步说明。
迁移你的项目
更新 Tailwind CSS
Tailwind CSS v4 在配置方法上引入了重大更改。官方的 Tailwind 升级工具将帮助自动化大部分迁移过程。
- 创建一个
main.css
文件并将其导入到你的nuxt.config.ts
文件中
@import "tailwindcss";
export default defineNuxtConfig({
css: ['~/assets/css/main.css']
})
- 运行 Tailwind CSS 升级工具
npx @tailwindcss/upgrade
更新 Nuxt UI
- 安装最新版本的包
pnpm add @nuxt/ui
yarn add @nuxt/ui
npm install @nuxt/ui
bun add @nuxt/ui
pnpm add @nuxt/ui-pro
yarn add @nuxt/ui-pro
npm install @nuxt/ui-pro
bun add @nuxt/ui-pro
- 在你的 CSS 中导入它
app/assets/css/main.css
@import "tailwindcss";
@import "@nuxt/ui";
app/assets/css/main.css
@import "tailwindcss";
@import "@nuxt/ui-pro";
- 使用 App 组件包装你的应用
- 在你的
nuxt.config.ts
文件中添加@nuxt/ui-pro
模块,因为它不再是一个层(layer)
nuxt.config.ts
export default defineNuxtConfig({
- extends: ['@nuxt/ui-pro'],
- modules: ['@nuxt/ui']
+ modules: ['@nuxt/ui-pro']
})
- 使用 App 组件包装你的应用
app.vue
<template>
<UApp>
<NuxtPage />
</UApp>
</template>
v2 中的变更
更新项目后,你可以开始迁移代码了。以下是 Nuxt UI v3 中所有重大更改的全面列表。
更新的设计系统
在 Nuxt UI v2 中,我们的设计系统混合使用了 primary
、gray
、error
等别名以及 Tailwind CSS 的所有颜色。我们将其替换为一个包含 7 个颜色别名的正式设计系统。
颜色 | 默认 | 描述 |
---|---|---|
primary | green | 主要品牌色,用作组件的默认颜色。 |
secondary | blue | 辅助颜色,用于补充主色。 |
success | green | 用于表示成功状态。 |
info | blue | 用于表示信息状态。 |
warning | yellow | 用于表示警告状态。 |
error | red | 用于表示表单验证错误状态。 |
neutral | slate | 中性颜色,用于背景、文本等。 |
此更改引入了一些你需要注意的重大更改
gray
颜色已重命名为neutral
<template>
- <p class="text-gray-500 dark:text-gray-400" />
+ <p class="text-neutral-500 dark:text-neutral-400" />
</template>
你还可以使用新的设计令牌来处理亮色和暗色模式
<template>
- <p class="text-gray-500 dark:text-gray-400" />
+ <p class="text-muted" />
- <p class="text-gray-900 dark:text-white" />
+ <p class="text-highlighted" />
</template>
color
属性中的gray
、black
和white
已被移除,改为使用neutral
- <UButton color="black" />
+ <UButton color="neutral" />
- <UButton color="gray" />
+ <UButton color="neutral" variant="subtle" />
- <UButton color="white" />
+ <UButton color="neutral" variant="outline" />
- 你不能再在
color
属性中使用 Tailwind CSS 的颜色,请改用新的别名
- <UButton color="red" />
+ <UButton color="error" />
app.config.ts
中的颜色配置已移至一个colors
对象中
export default defineAppConfig({
ui: {
- primary: 'green',
- gray: 'cool'
+ colors: {
+ primary: 'green',
+ neutral: 'slate'
+ }
}
})
更新的主题系统
Nuxt UI 组件现在使用 Tailwind Variants API 进行样式设置,这使得你之前通过 app.config.ts
和 ui
属性进行的覆盖配置都已过时。
- 更新你的
app.config.ts
,使用新主题来覆盖组件
export default defineAppConfig({
ui: {
button: {
- font: 'font-bold',
- default: {
- size: 'md',
- color: 'primary'
- }
+ slots: {
+ base: 'font-medium'
+ },
+ defaultVariants: {
+ size: 'md',
+ color: 'primary'
+ }
}
}
})
- 更新你的
ui
属性,使用新主题来覆盖每个组件的插槽
<template>
- <UButton :ui="{ font: 'font-bold' }" />
+ <UButton :ui="{ base: 'font-bold' }" />
</template>
已重命名的组件
我们重命名了一些 Nuxt UI 组件,使其与 Reka UI 的命名约定对齐
v2 | v3 |
---|---|
Divider | Separator |
Dropdown | DropdownMenu |
FormGroup | FormField |
Range | Slider |
Toggle | Switch |
Notification | Toast |
VerticalNavigation | NavigationMenu 和 orientation="vertical" |
HorizontalNavigation | NavigationMenu 和 orientation="horizontal" |
以下是已重命名或移除的 Nuxt UI Pro 组件
v1 | v3 |
---|---|
BlogList | BlogPosts |
ColorModeToggle | ColorModeSwitch |
DashboardCard | 已移除(请改用 PageCard ) |
DashboardLayout | DashboardGroup |
DashboardModal | 已移除(请改用 Modal ) |
DashboardNavbarToggle | DashboardSidebarToggle |
DashboardPage | 已移除 |
DashboardPanelContent | 已移除(请改用 #body 插槽) |
DashboardPanelHandle | DashboardResizeHandle |
DashboardSection | 已移除(请改用 PageCard ) |
DashboardSidebarLinks | 已移除(请改用 NavigationMenu ) |
DashboardSlideover | 已移除(请改用 Slideover ) |
FooterLinks | 已移除(请改用 NavigationMenu ) |
HeaderLinks | 已移除(请改用 NavigationMenu ) |
LandingCard | 已移除(请改用 PageCard ) |
LandingCTA | PageCTA |
LandingFAQ | 已移除(请改用 PageAccordion ) |
LandingGrid | 已移除(请改用 PageGrid ) |
LandingHero | 已移除(请改用 PageHero ) |
LandingLogos | PageLogos |
LandingSection | PageSection |
LandingTestimonial | 已移除(请改用 PageCard ) |
NavigationAccordion | ContentNavigation |
NavigationLinks | ContentNavigation |
NavigationTree | ContentNavigation |
PageError | Error |
PricingCard | PricingPlan |
PricingGrid | PricingPlans |
PricingSwitch | 已移除(请改用 Switch 或 Tabs ) |
变更的组件
除了重命名的组件外,组件 API 也有许多变更。我们来详细说明其中最重要的部分
links
和options
属性为了保持一致性已重命名为items
<template>
- <USelect :options="countries" />
+ <USelect :items="countries" />
- <UHorizontalNavigation :links="links" />
+ <UNavigationMenu :items="links" />
</template>
此变更影响以下组件:
Breadcrumb
、HorizontalNavigation
、InputMenu
、RadioGroup
、Select
、SelectMenu
、VerticalNavigation
。- 不同组件中的
click
字段已被移除,改为使用原生的 VueonClick
事件
<script setup lang="ts">
const items = [{
label: 'Edit',
- click: () => {
+ onClick: () => {
console.log('Edit')
}
}]
</script>
此变更影响
Toast
组件以及所有具有 items
链接的组件,例如 NavigationMenu
、DropdownMenu
、CommandPalette
等。- 全局的
Modals
、Slideovers
和Notifications
组件已被移除,改为使用 App 组件
app.vue
<template>
+ <UApp>
+ <NuxtPage />
+ </UApp>
- <UModals />
- <USlideovers />
- <UNotifications />
</template>
- 现在使用
v-model:open
指令和default-open
属性来控制可见性
<template>
- <UModal v-model="open" />
+ <UModal v-model:open="open" />
</template>
此变更影响以下组件:
ContextMenu
、Modal
和 Slideover
,并使得 InputMenu
、Select
、SelectMenu
和 Tooltip
的可见性可控。- 现在默认插槽用于触发器,内容放在
#content
插槽内(使用此方法时不需要v-model:open
指令)
<script setup lang="ts">
- const open = ref(false)
</script>
<template>
- <UButton label="Open" @click="open = true" />
- <UModal v-model="open">
+ <UModal>
+ <UButton label="Open" />
+ <template #content>
<div class="p-4">
<Placeholder class="h-48" />
</div>
+ </template>
</UModal>
</template>
此变更影响以下组件:
Modal
、Popover
、Slideover
、Tooltip
。- 在
#content
插槽内添加了#header
、#body
和#footer
插槽,类似于Card
组件
<template>
- <UModal>
+ <UModal title="Title" description="Description">
- <div class="p-4">
+ <template #body>
<Placeholder class="h-48" />
+ </template>
- </div>
</UModal>
</template>
此变更影响以下组件:
Modal
、Slideover
。变更的可组合函数
useToast()
可组合函数中的timeout
属性已重命名为duration
<script setup lang="ts">
const toast = useToast()
- toast.add({ title: 'Invitation sent', timeout: 0 })
+ toast.add({ title: 'Invitation sent', duration: 0 })
</script>
useModal
和useSlideover
可组合函数已被移除,改为使用更通用的useOverlay
可组合函数
一些重要差异
- 现在使用
useOverlay
可组合函数来创建叠加层实例 - 可以等待已打开的叠加层返回结果
- 不再能使用
modal.close()
或slideover.close()
关闭叠加层,它们现在会自动关闭:要么是当从打开的组件中显式触发close
事件时,要么是叠加层自身关闭时(点击背景、按下 ESC 键等) - 要在父组件中捕获返回值,你必须显式触发一个带有期望值的
close
事件
<script setup lang="ts">
import { ModalExampleComponent } from '#components'
- const modal = useModal()
+ const overlay = useOverlay()
- modal.open(ModalExampleComponent)
+ const modal = overlay.create(ModalExampleComponent)
</script>
现在通过一个 props
属性传递属性
<script setup lang="ts">
import { ModalExampleComponent } from '#components'
- const modal = useModal()
+ const overlay = useOverlay()
const count = ref(0)
- modal.open(ModalExampleComponent, {
- count: count.value
- })
+ const modal = overlay.create(ModalExampleComponent, {
+ props: {
+ count: count.value
+ }
+ })
</script>
现在通过 close
事件来关闭模态框。modal.open
方法现在返回一个 Promise,当模态框关闭时,该 Promise 会解析为模态框的结果
<script setup lang="ts">
import { ModalExampleComponent } from '#components'
- const modal = useModal()
+ const overlay = useOverlay()
+ const modal = overlay.create(ModalExampleComponent)
- function openModal() {
- modal.open(ModalExampleComponent, {
- onSuccess() {
- toast.add({ title: 'Success!' })
- }
- })
- }
+ async function openModal() {
+ const result = await modal.open(ModalExampleComponent, {
+ count: count.value
+ })
+
+ if (result) {
+ toast.add({ title: 'Success!' })
+ }
+ }
</script>
此页面正在建设中,我们将定期改进。