pages
pages/необязателен: vue-router не подключается, если используется только app.vue. Чтобы явно включить файловый роутинг, задайте pages: true в nuxt.config или добавьте router.options.ts.Использование
Страницы — это Vue-компоненты с любым поддерживаемым расширением (по умолчанию .vue, .js, .jsx, .mjs, .ts или .tsx).
Nuxt автоматически создает маршрут для каждой страницы в вашей директории ~/pages/.
<template>
<h1>Index page</h1>
</template>
// https://vuejs.org/guide/extras/render-function.html
export default defineComponent({
render () {
return h('h1', 'Index page')
},
})
// https://nuxt.com/docs/3.x/examples/advanced/jsx
// https://vuejs.org/guide/extras/render-function.html#jsx-tsx
export default defineComponent({
render () {
return <h1>Index page</h1>
},
})
Файл pages/index.vue будет иметь маршрут / в вашем приложении.
Если используется app.vue, для вывода текущей страницы нужен <NuxtPage/>:
<template>
<div>
<!-- Разметка, общая для всех страниц, например, NavBar -->
<NuxtPage />
</div>
</template>
Страницы должны иметь один корневой элемент, чтобы между ними работали анимационные переходы. HTML-комментарии тоже считаются элементами.
Это означает, что когда маршрут рендерится на сервере или генерируется статически, вы сможете увидеть его содержимое правильно, но когда вы перейдете к этому маршруту во время навигации на клиенте, переход между маршрутами будет неудачным, и вы увидите, что маршрут не рендерится.
Вот несколько примеров, которые иллюстрируют, как выглядит страница с одним корневым элементом:
<template>
<div>
<!-- Эта страница правильно содержит один корневой элемент -->
Контент страницы
</div>
</template>
<template>
<!-- Эта страница не будет отображаться при изменении маршрута во время навигации на клиенте из-за этого комментария -->
<div>Контент страницы</div>
</template>
<template>
<div>Эта страница</div>
<div>Имеет более одного корневого элемента</div>
<div>И не будет рендериться при изменении маршрута во время навигации на клиенте</div>
</template>
Динамические маршруты
Содержимое в квадратных скобках в имени файла или папки становится параметром динамического маршрута. Можно комбинировать несколько параметров и обычный текст в пути.
Чтобы параметр был необязательным, заключите его в двойные скобки: ~/pages/[[slug]]/index.vue или ~/pages/[[slug]].vue — тогда подойдут и /, и /test.
-| pages/
---| index.vue
---| users-[group]/
-----| [id].vue
Данный пример показывает, что вы можете получить доступ к group/id внутри вашего компонента через объект $route:
<template>
<p>{{ $route.params.group }} - {{ $route.params.id }}</p>
</template>
При переходе по маршруту /users-admins/123 отрендерит:
<p>admins - 123</p>
Если вы используете Composition API, то доступ к объекту маршрута можно получить, вызвав глобальную функцию useRoute, которая позволит вам получить доступ к маршруту так же, как this.$route в Options API.
<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. Используйте
~/pages/foo/index.vue и ~/pages/foo/[slug].vue для сопоставления /foo и /foo/hello между разными страницами.Catch-all маршрут
Если нужен catch-all-маршрут, добавьте файл [...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, вы должны вставить компонент <NuxtPage> внутрь pages/parent.vue:
<template>
<div>
<h1>Я родительский элемент</h1>
<NuxtPage :foobar="123" />
</div>
</template>
<script setup lang="ts">
const props = defineProps({
foobar: String,
})
console.log(props.foobar)
</script>
Ключи дочерних маршрутов
Если вы хотите больше контролировать повторный рендер <NuxtPage> компонента (например, для переходов), то вы можете передавать строку или функцию во входной параметр pageKey или определить значение key через definePageMeta:
<template>
<div>
<h1>Я родительский элемент</h1>
<NuxtPage :page-key="route => route.fullPath" />
</div>
</template>
Или:
<script setup lang="ts">
definePageMeta({
key: route => route.fullPath,
})
</script>
Группы маршрутов
В некоторых случаях вам может понадобиться сгруппировать набор маршрутов таким образом, чтобы это не повлияло на маршрутизацию на основе файлов. Для этой цели вы можете поместить файлы в директорию, заключенную в скобки - ( и ).
Например:
-| pages/
---| index.vue
---| (marketing)/
-----| about.vue
-----| contact.vue
Это создаст в приложении страницы /, /about и /contact. Группа marketing игнорируется в структуре URL-адреса.
Доступ к группам маршрутов
Группы маршрутов автоматически попадают в метаданные маршрута как route.meta.groups.
Так можно использовать информацию о группе в компонентах для условной логики, стилей и других задач.
<script setup lang="ts">
const route = useRoute()
console.log(route.meta.groups) // Output: ['marketing']
</script>
<template>
<div>
<p v-if="route.meta.groups?.includes('marketing')">
Это маркетинговая страница
</p>
</div>
</template>
Метаданные страницы
Метаданные маршрута задаются макросом 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'
function validateIdParam (route) {
return route.params.id && !Number.isNaN(Number(route.params.id))
}
const title = ref('')
definePageMeta({
validate: validateIdParam,
someData,
title, // так делать нельзя: ref будет вынесен из компонента
})
</script>
Особые поля метаданных
Свои ключи в definePageMeta можно задавать свободно. Ниже — поля со специальным смыслом в Nuxt:
alias
Псевдонимы маршрута: та же страница открывается по разным путям. Значение — строка или массив строк, см. документацию vue-router.
keepalive
При keepalive: true в definePageMeta Nuxt оборачивает страницу в <KeepAlive> — удобно для сохранения состояния, например у родителя с динамическими дочерними маршрутами.
Для родительских маршрутов можно использовать <NuxtPage keepalive /> и передать пропсы в <KeepAlive> (список).
Вы также можете установить значения по умолчанию для этого свойства в вашем nuxt.config.
key
layout
Можно задать лейаут для маршрута: false (без лейаута), строка с именем или ref/computed для реактивного выбора. Подробнее о лейаутах.
layoutTransition и pageTransition
Можно задать опции для <transition> вокруг страниц и лейаутов или передать false, чтобы отключить обёртку. Список опций — в API Vue, поведение — в руководстве.
Вы также можете установить значения по умолчанию для этого свойства в вашем nuxt.config.
middleware
Middleware до загрузки страницы сливается с цепочками родительских и дочерних маршрутов. Допустимы строка, функция в духе global before guards vue-router или массив. Подробнее — middleware маршрута.
name
Вы можете задать имя для маршрута страницы.
path
Поле path задаёт собственный шаблон маршрута, если имени файла недостаточно. См. vue-router.
props
Пробрасывает params маршрута в страницу как пропсы. См. vue-router.
Типизация пользовательских мета-данных
Если вы хотите добавить типизацию мета-данных на ваши страницы, вы можете сделать это безопасным способом. Можно дополнить тип объекта, принимаемого definePageMeta:
declare module '#app' {
interface PageMeta {
pageType?: string
}
}
// При расширении типов важно импортировать или экспортировать хотя бы один символ
export {}
Навигация
Для навигации между страницами в вашем приложении вы можете использовать компонент <NuxtLink>.
Этот компонент входит в состав Nuxt, его не нужно импортировать вручную, в отличие от обычных компонентов.
Например, ссылка на страницу index.vue в папке pages:
<template>
<NuxtLink to="/">Домашняя страница</NuxtLink>
</template>
Программная навигация
Nuxt позволяет осуществлять программную навигацию с помощью метода navigateTo(). Используя этот метод, вы можете перемещать пользователя между страницами в вашем приложении. Это отлично подходит для обработки ввода от пользователя и динамической навигации по всему приложению. В этом примере у нас есть простой метод navigate(), который вызывается, когда пользователь отправляет форму поиска.
await с navigateTo или возвращайте цепочку результатов из функции.<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>
Клиентские страницы
Вы можете определить страницу как только на клиенте, для этого добавьте суффикс .client.vue. Никакое содержимое этой страницы не будет отображено на сервере.
Серверные страницы
Вы можете определить страницу как только на сервере, добавив суффикс .server.vue. Хотя вы сможете перейти на эту страницу с помощью навигации на стороне клиента, управляемой vue-router, она будет автоматически рендериться серверным компонентом, что означает, что код, необходимый для рендеринга страницы, не будет включен в ваш клиентский бандл.
Пользовательский роутинг
По мере роста и усложнения вашего приложения маршрутизация может потребовать большей гибкости. По этой причине Nuxt напрямую предоставляет маршрутизатор, маршруты и опции маршрутизатора для настройки различными способами.
Многостраничная директория
По умолчанию все ваши страницы находятся в корне вашего проекта в директории pages.
Однако вы можете использовать слои Nuxt для создания групп страниц вашего приложения:
-| 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'],
})