路由
Nuxt 的一个核心特性是文件系统路由。pages/
目录中的每个 Vue 文件都会创建一个对应的 URL(或路由),用于显示该文件的内容。通过对每个页面使用动态导入,Nuxt 利用代码分割机制,传输请求路由所需的最小 JavaScript。
页面
Nuxt 路由基于 vue-router,并从 pages/
目录中创建的每个组件生成路由,路由的生成基于文件名。
这种文件系统路由使用命名约定来创建动态和嵌套路由:
-| pages/
---| about.vue
---| index.vue
---| posts/
-----| [id].vue
{
"routes": [
{
"path": "/about",
"component": "pages/about.vue"
},
{
"path": "/",
"component": "pages/index.vue"
},
{
"path": "/posts/:id",
"component": "pages/posts/[id].vue"
}
]
}
导航
<NuxtLink>
组件用于链接各页面。它渲染一个 <a>
标签,href
属性设置为页面的路由。一旦应用被水合,页面之间的过渡将在 JavaScript 中通过更新浏览器 URL 来实现。这可以防止全页面刷新并允许动画过渡。
当一个 <NuxtLink>
进入客户端视口时,Nuxt 会自动预取链接页面的组件和有效载荷(生成的页面),从而实现更快的导航。
<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>
路由参数
可以在 <script setup>
块或 Vue 组件的 setup()
方法中使用 useRoute()
composable 访问当前路由的详细信息。
<script setup lang="ts">
const route = useRoute()
// 当访问 /posts/1 时,route.params.id 将为 1
console.log(route.params.id)
</script>
路由中间件
Nuxt 提供了一个可自定义的路由中间件框架,您可以在整个应用程序中使用,特别适合提取您希望在导航到特定路由之前运行的代码。
有三种类型的路由中间件:
- 匿名(或内联)路由中间件,直接在使用它们的页面中定义。
- 命名路由中间件,放置在
middleware/
目录中,使用时将通过异步导入自动加载。(注意: 路由中间件名称会被规范化为 kebab-case,因此someMiddleware
变为some-middleware
。) - 全局路由中间件,放置在
middleware/
目录 中(带有.global
后缀),将在每次路由更改时自动运行。
以下是一个 auth
中间件示例,用于保护 /dashboard
页面:
export default defineNuxtRouteMiddleware((to, from) => {
// isAuthenticated() 是一个示例方法,用于验证用户是否已认证
if (isAuthenticated() === false) {
return navigateTo('/login')
}
})
<script setup lang="ts">
definePageMeta({
middleware: 'auth'
})
</script>
<template>
<h1>欢迎来到您的仪表盘</h1>
</template>
路由验证
Nuxt 提供了通过每个希望验证的页面中的 validate
属性来进行路由验证,该属性位于 definePageMeta()
中。
validate
属性接受 route
作为参数。您可以返回一个布尔值来确定这是一个有效的路由还是由这个页面渲染的路由。如果返回 false
,并且找不到其他匹配项,将导致 404 错误。您还可以直接返回一个带有 statusCode
/ statusMessage
的对象,立即以错误响应(将不检查其他匹配项)。
如果您有更复杂的用例,则可以使用匿名路由中间件。
<script setup lang="ts">
definePageMeta({
validate: async (route) => {
// 检查 id 是否由数字组成
return typeof route.params.id === 'string' && /^\d+$/.test(route.params.id)
}
})
</script>