Nuxt3 中文课程 《实战全栈开发简书》.

路由

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

Nuxt的核心功能之一是文件系统路由。pages/目录中的每个Vue文件都会创建一个相应的URL(或路由),用于显示文件的内容。通过为每个页面使用动态导入,Nuxt利用代码分割来仅加载所需路由的最小量JavaScript。

页面

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

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

| pages/
---| about.vue
---| index.vue
---| posts/
-----| [id].vue
Read more in Docs > Guide > Directory Structure > Pages.

导航

<NuxtLink> 组件用于在页面之间创建链接。它会将<a>标签渲染为具有href属性设置为页面的路由。一旦应用程序被渲染,页面的切换将在JavaScript中进行,通过更新浏览器URL来实现。这样可以避免整页刷新,同时允许实现动画过渡效果。

<NuxtLink>在客户端视口中可见时,Nuxt会自动预取链接页面的组件和负载(生成的页面),从而加快导航速度。

pages/app.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>
Read more in Docs > API > Components > Nuxt Link.

路由参数

useRoute()组合式函数可在Vue组件的<script setup>块或setup()方法中使用,以访问当前路由的详细信息。

pages/posts/[id].vue
<script setup lang="ts">
const route = useRoute()

// 当访问/posts/1时,route.params.id将为1
console.log(route.params.id)
</script>
Read more in Docs > API > Composables > Use Route.

路由中间件

Nuxt提供了一个可自定义的路由中间件框架,您可以在应用程序中使用,非常适合提取在导航到特定路由之前要运行的代码。

路由中间件在Nuxt应用程序的Vue部分中运行。尽管名称相似,但它们与在应用程序的Nitro服务器部分中运行的服务器中间件完全不同。

有三种类型的路由中间件:

  1. 匿名(或内联)路由中间件,直接在使用它们的页面中定义。
  2. 命名路由中间件,放置在middleware/目录中,当在页面中使用时,会通过异步导入自动加载。(注意:路由中间件名称会转换为短横线分隔命名,因此someMiddleware会变成some-middleware。)
  3. 全局路由中间件,放置在middleware/目录中(使用.global后缀),将在每次路由更改时自动运行。

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

export default defineNuxtRouteMiddleware((to, from) => {
  // isAuthenticated()是一个验证用户是否已经认证的示例方法
  if (isAuthenticated() === false) {
    return navigateTo('/login')
  }
})
Read more in Docs > Guide > Directory Structure > Middleware.

路由验证

Nuxt通过每个要验证的页面中的definePageMeta()validate属性提供路由验证。

validate属性接受route作为参数。您可以返回一个布尔值来确定是否将此路由视为有效路由以渲染此页面。如果返回false,并且找不到其他匹配项,这将导致404错误。您还可以直接返回一个带有statusCode/statusMessage的对象以立即响应错误(其他匹配项将不会被检查)。

如果您有更复杂的用例,可以使用匿名路由中间件代替。

pages/posts/[id].vue
<script setup lang="ts">
definePageMeta({
  validate: async (route) => {
    // 检查id是否由数字组成
    return /^\d+$/.test(route.params.id)
  }
})
</script>
Read more in Docs > API > Utils > Define Page Meta.