页面和布局

学习如何将 Nuxt 2 的页面和布局迁移到 Nuxt 3。

app.vue

Nuxt 3 通过 ~/app.vue 为你的应用提供了一个中央入口点。

如果你的源目录中没有 app.vue 文件,Nuxt 将使用它自己的默认版本。

这个文件是放置任何在应用启动时只需运行一次的自定义代码的绝佳位置,也适合放置在应用每个页面都存在的组件。例如,如果你只有一个布局,可以将其移到 app.vue 中。

Read more in Docs > 4 X > Guide > Directory Structure > App.
Read and edit a live example in Docs > 4 X > Examples > Hello World.

迁移

考虑创建一个 app.vue 文件,并将任何需要在应用顶层只运行一次的逻辑放入其中。你可以在 此处查看示例

布局

如果你的应用在多个页面中使用布局,仅需做很小的更改。

在 Nuxt 2 中,布局中使用 <Nuxt> 组件来渲染当前页面。在 Nuxt 3 中,布局改为使用插槽,因此你需要将该组件替换为 <slot />。这也允许使用具名插槽和作用域插槽的高级用例。 阅读有关布局的更多内容

你还需要更改在页面中定义要使用的布局的方式,使用 definePageMeta 编译宏。布局名称将转换为 kebab-case。因此 app/layouts/customLayout.vue 在页面中引用时将变成 custom-layout

迁移

  1. <Nuxt /> 替换为 <slot />
    app/layouts/custom.vue
      <template>
        <div id="app-layout">
          <main>
    -       <Nuxt />
    +       <slot />
          </main>
        </div>
      </template>
    
  2. 使用 definePageMeta 来选择页面使用的布局。
    app/pages/index.vue
    + <script setup>
    + definePageMeta({
    +   layout: 'custom'
    + })
    - <script>
    - export default {
    -   layout: 'custom'
    - }
      </script>
    
  3. ~/layouts/_error.vue 移动到 ~/error.vue。参见 错误处理文档。如果你想确保该页面使用某个布局,可以在 error.vue 中直接使用 <NuxtLayout>
    error.vue
    <template>
      <div>
        <NuxtLayout name="default">
          <!-- -->
        </NuxtLayout>
      </div>
    </template>
    

页面

当源目录中存在 app/pages/ 目录时,Nuxt 3 会提供一个可选的 vue-router 集成。如果你只有一个页面,考虑将其移动到 app.vue 以获得更轻量的构建。

动态路由

在 Nuxt 3 中定义动态路由的格式与 Nuxt 2 略有不同,因此你可能需要重命名 app/pages/ 中的一些文件。

  1. 之前使用 _id 来定义动态路由参数,现在使用 [id]
  2. 之前使用 _.vue 来定义 catch-all 路由,现在使用 [...slug].vue

嵌套路由

在 Nuxt 2 中,你会使用 <Nuxt><NuxtChild> 来定义任何嵌套路由(带父组件和子组件)。在 Nuxt 3 中,它们已被单个 <NuxtPage> 组件取代。

页面键和 keep-alive 属性

如果你之前把自定义页面键或 keep-alive 属性传递给 <Nuxt>,现在需要使用 definePageMeta 来设置这些选项。

Read more in Docs > 4 X > Guide > Directory Structure > App > Pages#special Metadata.

页面和布局过渡

如果你在组件选项中直接为页面或布局定义了过渡,现在需要使用 definePageMeta 来设置过渡。自 Vue 3 起,-enter 和 -leave CSS 类已被重命名。当在 <slot> 上使用时,<Nuxt>style 属性不再对过渡生效,因此请将样式移动到你的 -active 类。

Read more in Docs > 4 X > Getting Started > Transitions.

迁移

  1. 将任何带动态参数的页面重命名为符合新格式的名称。
  2. <Nuxt><NuxtChild> 更新为 <NuxtPage>
  3. 如果你使用 Composition API,也可以将 this.$routethis.$router 迁移为使用 useRouteuseRouter 组合式函数。

示例:动态路由

- URL: /users
- Page: /pages/users/index.vue

- URL: /users/some-user-name
- Page: /pages/users/_user.vue
- Usage: params.user

- URL: /users/some-user-name/edit
- Page: /pages/users/_user/edit.vue
- Usage: params.user

- URL: /users/anything-else
- Page: /pages/users/_.vue
- Usage: params.pathMatch

示例:嵌套路由 和 definePageMeta

<template>
  <div>
    <NuxtChild
      keep-alive
      :keep-alive-props="{ exclude: ['modal'] }"
      :nuxt-child-key="$route.slug"
    />
  </div>
</template>

<script>
export default {
  transition: 'page', // or { name: 'page' }
}
</script>

全局 NuxtLink 组件的大部分语法和功能保持不变。如果你一直在使用快捷形式 <NLink>,应将其更新为 <NuxtLink>

<NuxtLink> 现在可以作为所有链接的替代项,即使是外部链接。你可以阅读更多内容,了解如何扩展它以提供自定义的链接组件。

Read more in Docs > 4 X > API > Components > Nuxt Link.

编程式导航

从 Nuxt 2 迁移到 Nuxt 3 时,你需要更新如何以编程方式导航用户。在 Nuxt 2 中,你可以通过 this.$router 访问底层的 Vue Router。在 Nuxt 3 中,你可以使用 navigateTo() 工具方法,它允许你将路由和参数传递给 Vue Router。

确保始终对 navigateTo 使用 await,或通过从函数返回其结果来链式处理。
<script>
export default {
  methods: {
    navigate () {
      this.$router.push({
        path: '/search',
        query: {
          name: 'first name',
          type: '1',
        },
      })
    },
  },
}
</script>