迁移
将您的应用程序从 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
模块,因为它不再是一个层级
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 | 绿色 | 主要品牌色,用作组件的默认颜色。 |
secondary | 蓝色 | 补充主色的次要颜色。 |
success | 绿色 | 用于成功状态。 |
info | 蓝色 | 用于信息状态。 |
warning | 黄色 | 用于警告状态。 |
error | 红色 | 用于表单错误验证状态。 |
neutral | 石板灰 | 用于背景、文本等的中性颜色。 |
此更改引入了您需要注意的几个破坏性变更
- 将
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 专业版组件
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 | 错误 |
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
方法现在返回一个实例,该实例可用于在模态框关闭时等待模态框的结果
<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>
此页面正在完善中,我们会定期进行改进。