迁移
将您的应用程序从 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/content
yarn add @nuxt/content
npm install @nuxt/content
bun add @nuxt/content
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模块,因为它不再是一个层:
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'
+ }
}
}
})
- 更新您的
uiprops 以使用其新主题覆盖每个组件的插槽:
<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 with orientation="vertical" |
HorizontalNavigation | NavigationMenu with orientation="horizontal" |
以下是已重命名或删除的 Nuxt UI Pro 组件:
| v1 | v3 |
|---|---|
BlogList | BlogPosts |
ColorModeToggle | ColorModeSwitch |
DashboardCard | Removed (use PageCard instead) |
DashboardLayout | DashboardGroup |
DashboardModal | Removed (use Modal instead) |
DashboardNavbarToggle | DashboardSidebarToggle |
DashboardPage | Removed |
DashboardPanelContent | Removed (use #body slot instead) |
DashboardPanelHandle | DashboardResizeHandle |
DashboardSection | Removed (use PageCard instead) |
DashboardSidebarLinks | Removed (use NavigationMenu instead) |
DashboardSlideover | Removed (use Slideover instead) |
FooterLinks | Removed (use NavigationMenu instead) |
HeaderLinks | Removed (use NavigationMenu instead) |
LandingCard | Removed (use PageCard instead) |
LandingCTA | PageCTA |
LandingFAQ | Removed (use PageAccordion instead) |
LandingGrid | Removed (use PageGrid instead) |
LandingHero | Removed (use PageHero instead) |
LandingLogos | PageLogos |
LandingSection | PageSection |
LandingTestimonial | Removed (use PageCard instead) |
NavigationAccordion | ContentNavigation |
NavigationLinks | ContentNavigation |
NavigationTree | ContentNavigation |
PageError | Error |
PricingCard | PricingPlan |
PricingGrid | PricingPlans |
PricingSwitch | Removed (use Switch or Tabs instead) |
更改的组件
除了重命名的组件,组件 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。#header、#body和#footer插槽已添加到#content插槽内部,类似于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 方法现在返回一个实例,该实例可用于在模态框关闭时等待模态框的结果:
<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 instance = modal.open(ModalExampleComponent, {
+ count: count.value
+ })
+
+ const result = await instance.result
+
+ if (result) {
+ toast.add({ title: 'Success!' })
+ }
+ }
</script>
更改了表单验证
用于定位表单字段的错误对象属性已从 path 重命名为 name:
<script setup lang="ts">
const validate = (state: any): FormError[] => {
const errors = []
if (!state.email) {
errors.push({
- path: 'email',
+ name: 'email',
message: 'Required'
})
}
if (!state.password) {
errors.push({
- path: 'password',
+ name: 'password',
message: 'Required'
})
}
return errors
}
</script>
此页面正在施工中,我们将定期改进。