pages
app.vue
,vue-router
将不会被包含在内。要强制使用页面系统,请在 nuxt.config
中设置 pages: true
,或者在 app/router.options.ts
中设置。使用方法
页面是 Vue 组件,可以使用 Nuxt 支持的任何有效扩展名(默认为 .vue
、.js
、.jsx
、.mjs
、.ts
或 .tsx
)。
Nuxt 会自动为 ~/pages/
目录中的每个页面创建一个路由。
<template>
<h1>首页</h1>
</template>
pages/index.vue
文件将映射到应用程序的 /
路由。
如果你正在使用 app.vue
,请确保使用 <NuxtPage/>
组件来显示当前页面:
<template>
<div>
<!-- 所有页面共享的标记,例如导航栏 -->
<NuxtPage />
</div>
</template>
页面必须有一个单一的根元素,以允许页面之间的路由过渡,HTML 注释也被视为元素。
这意味着当路由在服务器端渲染或静态生成时,你将能够正确地看到其内容,但当你在客户端导航到该路由时,路由之间的过渡将失败,你将看到该路由不会被渲染。
以下是一些示例,以说明具有单一根元素的页面的外观:
<template>
<div>
<!-- 此页面正确地只有一个单一根元素 -->
页面内容
</div>
</template>
动态路由
如果你在方括号中放置任何内容,它将被转换为动态路由参数。你可以在文件名或目录中混合和匹配多个参数,甚至可以包含非动态文本。
如果你想要一个参数是可选的,你必须将其放在双方括号中 - 例如,~/pages/[[slug]]/index.vue
或 ~/pages/[[slug]].vue
将同时匹配 /
和 /test
。
-| pages/
---| index.vue
---| users-[group]/
-----| [id].vue
在上面的示例中,你可以通过 $route
对象在组件中访问 group/id:
<template>
<p>{{ $route.params.group }} - {{ $route.params.id }}</p>
</template>
导航到 /users-admins/123
将渲染:
<p>admins - 123</p>
如果你想要使用 Composition API 访问路由,可以使用全局的 useRoute
函数,它允许你像 Options API 中的 this.$route
一样访问路由。
<script setup lang="ts">
const route = useRoute()
if (route.params.group === 'admins' && !route.params.id) {
console.log('警告!确保用户已经通过身份验证!')
}
</script>
/foo/hello
路由,~/pages/foo.vue
将优先于 ~/pages/foo/[slug].vue
。:br 使用 ~/pages/foo/index.vue
和 ~/pages/foo/[slug].vue
来匹配不同页面的 /foo
和 /foo/hello
。全匹配路由
如果你需要一个全匹配路由,你可以创建一个名为 [...slug].vue
的文件。这将匹配该路径下的所有路由。
<template>
<p>{{ $route.params.slug }}</p>
</template>
导航到 /hello/world
将渲染:
<p>["hello", "world"]</p>
嵌套路由
你可以使用 <NuxtPage>
显示嵌套路由。
示例:
-| pages/
---| parent/
------| child.vue
---| parent.vue
这个文件树将生成以下路由:
[
{
path: '/parent',
component: '~/pages/parent.vue',
name: 'parent',
children: [
{
path: 'child',
component: '~/pages/parent/child.vue',
name: 'parent-child'
}
]
}
]
要显示 child.vue
组件,你需要在 pages/parent.vue
中插入 <NuxtPage>
组件:
<template>
<div>
<h1>我是父视图</h1>
<NuxtPage :foobar="123" />
</div>
</template>
子路由键
如果你想要更多地控制 <NuxtPage>
组件何时重新渲染(例如,用于过渡效果),你可以通过 pageKey
属性传递字符串或函数,或者通过 definePageMeta
定义 key
值:
<template>
<div>
<h1>我是父视图</h1>
<NuxtPage :page-key="route => route.fullPath" />
</div>
</template>
或者:
<script setup lang="ts">
definePageMeta({
key: route => route.fullPath
})
</script>
页面元数据
你可能希望为应用程序中的每个路由定义元数据。你可以使用 definePageMeta
宏来实现,它在 <script>
和 <script setup>
中都可以使用:
<script setup lang="ts">
definePageMeta({
title: '我的主页'
})
</script>
然后,你可以在应用程序的其他部分通过 route.meta
对象访问这些数据。
<script setup lang="ts">
const route = useRoute()
console.log(route.meta.title) // 我的主页
</script>
如果你使用嵌套路由,所有这些路由的页面元数据将合并为一个单独的对象。有关路由元数据的更多信息,请参阅vue-router 文档。
与 defineEmits
或 defineProps
(参见Vue 文档)类似,definePageMeta
是一个编译器宏。它将被编译掉,所以你不能在组件内部引用它。相反,传递给它的元数据将被提升出组件。因此,页面元数据对象不能引用组件(或在组件上定义的值)。但是,它可以引用导入的绑定。
<script setup lang="ts">
import { someData } from '~/utils/example'
const title = ref('')
definePageMeta({
title, // 这将导致错误
someData
})
</script>
特殊元数据
当然,你可以定义自己在整个应用程序中使用的元数据。但是,使用 definePageMeta
定义的某些元数据具有特定的目的:
alias
你可以定义页面别名。它们允许你从不同的路径访问相同的页面。它可以是一个字符串或字符串数组,如 vue-router 文档 中所定义。
keepalive
如果在 definePageMeta
中设置 keepalive: true
,Nuxt 将自动将你的页面包装在 Vue 的 <KeepAlive>
组件中。这在具有动态子路由的父级路由中可能很有用,如果你希望在路由更改时保留页面状态。
当你的目标是保留父级路由的状态时,请使用以下语法:<NuxtPage keepalive />
。你还可以设置要传递给 <KeepAlive>
的 props(参见这里的完整列表)。
你可以在你的 nuxt.config
中为此属性设置默认值(参考文档)。
key
见上文。
layout
你可以定义用于渲染路由的布局。这可以是 false(禁用任何布局),字符串或 ref/computed,如果你希望以某种方式使其响应。有关布局的更多信息。
layoutTransition
和 pageTransition
你可以为包装页面和布局的 <transition>
组件定义过渡属性,或者传递 false
以禁用该路由的 <transition>
包装器。你可以在这里查看可以传递的选项列表,或者阅读有关过渡的更多信息。
你可以在你的 nuxt.config
中为这些属性设置默认值(参考文档)。
middleware
你可以定义在加载此页面之前应用的中间件。它将与所有匹配的父/子路由中使用的其他中间件合并。它可以是一个字符串、一个函数(遵循全局前置守卫模式的匿名/内联中间件函数)或一个字符串/函数数组。有关命名中间件的更多信息。
name
你可以为此页面的路由定义一个名称。
path
如果你的模式比文件名更复杂,你可以定义一个路径匹配器。有关更多信息,请参阅vue-router 文档。
类型化自定义元数据
如果你为页面添加自定义元数据,你可能希望以类型安全的方式添加。可以通过增强 definePageMeta
接受的对象类型来实现:
declare module '#app' {
interface PageMeta {
pageType?: string
}
}
// 当增强类型时,始终确保导入/导出某些内容
export {}
导航
要在应用程序的页面之间导航,应该使用 <NuxtLink>
组件。
该组件包含在 Nuxt 中,因此你无需像其他组件一样导入它。
链接到 pages
文件夹中的 index.vue
页面的简单示例:
<template>
<NuxtLink to="/">首页</NuxtLink>
</template>
编程式导航
Nuxt 3 允许通过 navigateTo()
实用程序方法进行编程式导航。使用此实用程序方法,你将能够以编程方式引导用户在应用程序中导航。这对于从用户处获取输入并在应用程序中动态地引导他们非常有用。在此示例中,我们有一个名为 navigate()
的简单方法,当用户提交搜索表单时调用该方法。
**注意:**确保始终在 navigateTo
上使用 await
或从函数返回其结果。
<script setup lang="ts">
const name = ref('');
const type = ref(1);
function navigate(){
return navigateTo({
path: '/search',
query: {
name: name.value,
type: type.value
}
})
}
</script>
自定义路由
随着应用程序变得越来越大和复杂,你的路由可能需要更多的灵活性。因此,Nuxt 以不同的方式直接暴露了路由、路由和路由器选项,以供定制。
多个页面目录
默认情况下,所有页面应位于项目根目录下的一个 pages
目录中。
但是,你可以使用 Nuxt Layers 来创建应用程序页面的分组:
-| some-app/
---| nuxt.config.ts
---| pages
-----| app-page.vue
-| nuxt.config.ts
// some-app/nuxt.config.ts
export default defineNuxtConfig({
})
export default defineNuxtConfig({
extends: ['./some-app'],
})