Skip to content

路由

Nuxt 文件系统路由为 pages/ 目录中的每个文件创建对应的路由。

Nuxt 的一个核心特性是文件系统路由器pages/ 目录中的每一个 Vue 文件都会创建一个对应的 URL(或路由),用于显示该文件的内容。通过对每个页面使用动态导入,Nuxt 利用代码分割来只传输请求路由所需的最少 JavaScript 代码。

页面

Nuxt 的路由基于 vue-router,并根据 pages/ 目录 中每个组件的文件名生成路由。

此文件系统路由使用命名约定来创建动态和嵌套路由:

vue
-| pages/
---| about.vue
---| index.vue
---| posts/
-----| [id].vue
js
{
  "routes": [
    {
      "path": "/about",
      "component": "pages/about.vue"
    },
    {
      "path": "/",
      "component": "pages/index.vue"
    },
    {
      "path": "/posts/:id",
      "component": "pages/posts/[id].vue"
    }
  ]
}
  • 默认路由

index.html通常也被称为默认路由

  • 动态路由

使用方括号 [param] 创建动态路由,例如 pages/posts/[id].vue 会映射为 /posts/:id

  • 嵌套路由
sh
pages/parent.vue
pages/parent/child.vue

将生成 /parent/parent/child,其中 /parent 的组件中需放 来呈现子路由内容。

导航

<NuxtLink>组件用于在页面之间链接。它会渲染一个带有指向页面路由的 href 属性的 <a> 标签。应用程序完成水化后,页面切换通过 JavaScript 更新浏览器 URL 来执行。这避免了整页刷新,并支持动画过渡效果。

<NuxtLink>在客户端视口内出现时,Nuxt 会自动预取链接页面的组件及其载荷(生成的页面),从而实现更快的导航。

pages/app.vue
vue
<template>
  <header>
    <nav>
      <ul>
        <li><NuxtLink to="/about">关于</NuxtLink></li>
        <li><NuxtLink to="/posts/1">文章 1</NuxtLink></li>
        <li><NuxtLink to="/posts/2">文章 2</NuxtLink></li>
      </ul>
    </nav>
  </header>
</template>

路由中间件

Nuxt 提供了一个可自定义的路由中间件框架,可在应用中随处使用,非常适合提取需要在导航到特定路由前执行的代码。

路由中间件分为三类:

  1. 匿名(或内联)路由中间件,直接定义在使用它们的页面中。
  2. 命名路由中间件,放在 middleware/ 目录中,当在页面使用时会通过异步导入自动加载。(注意:路由中间件名称会标准化为 kebab-case,例如 someMiddleware 会变成 some-middleware。)
  3. 全局路由中间件,放在 middleware/ 目录中,文件名带有 .global 后缀,会在每次路由变化时自动运行。

下面是 auth 中间件保护 /dashboard 页面示例:

ts
export default defineNuxtRouteMiddleware((to, from) => {
  // isAuthenticated() 是一个示例方法,用于验证用户是否已认证
  if (isAuthenticated() === false) {
    return navigateTo('/login')
  }
})
vue
<script setup lang="ts">
definePageMeta({
  middleware: 'auth'
})
</script>

<template>
  <h1>欢迎来到您的仪表盘</h1>
</template>

路由校验

Nuxt 通过每个页面中 definePageMeta()validate 属性提供路由校验功能。

validate 属性接受当前路由作为参数。你可以返回布尔值以判断该路由是否为此页面的有效路由。如果返回 false,将触发 404 错误。你也可以直接返回包含 statusCode/statusMessage 的对象来自定义错误响应。

pages/posts/[id
vue
<script setup lang="ts">
definePageMeta({
  validate: async (route) => {
    // 校验 id 是否由数字组成
    return typeof route.params.id === 'string' && /^\d+$/.test(route.params.id)
  }
})
</script>

路由传参

Nuxt 3 内置的 useRoute 可以直接拿到路由对象

传参方式定义方式使用语法获取方式
路径参数(Params)文件名为 [id].vue<NuxtLink :to="{ name, params }">router.push({ name, params })route.params.xxx
查询参数(Query)URL 后面的 ?key=value<NuxtLink :to="{ path, query }">router.push({ path, query })route.query.xxx

params

如果你在 pages/ 目录下有文件名为 [id].vue 的组件,它会自动映射到路径如 /posts/123,其中 id = '123'

在组件中可以通过 useRoute() 获取参数:

<script setup>
const route = useRoute()
console.log(route.params.id) // => '123'
</script>

在模板中也可直接使用 $route.params.id 显示参数。自定义路由

query

通过 useRoute() 获取 route.query.id,可以支持页面刷新后仍能读取参数:

const id = ref(route.query.id ?? '')

编程式导航

  • 方式一(路径方式):

    router.push('/project?id=123')
  • 方式二(命名路由 + params):

    router.push({ name: 'project', params: { id: 123 } })
  • 方式三(路径 + query):

    router.push({ path: '/project', query: { id: 123 } })

注意

如果使用 path,则 params 会被忽略,必须搭配 name 使用 params。