Урок 02

Файловый роутинг

Принцип

Структура pages/ = структура URL.

pages/
├── index.vue           → /
├── about.vue           → /about
├── contact.vue         → /contact
├── users/
│   ├── index.vue       → /users
│   ├── list.vue        → /users/list
│   └── new.vue         → /users/new
└── blog/
    ├── index.vue       → /blog
    └── post-1.vue      → /blog/post-1

Никаких роутеров. Создал файл — есть страница.

Базовые страницы

pages/index.vue → /

<template>
    <h1>Главная</h1>
</template>

pages/about.vue → /about

<template>
    <h1>О нас</h1>
</template>

Вложенные папки

pages/users/index.vue → /users

<template>
    <h1>Список пользователей</h1>
</template>

pages/users/new.vue → /users/new

<template>
    <h1>Новый пользователь</h1>
</template>

Динамические маршруты

[param] — динамический параметр.

pages/users/[id].vue → /users/1, /users/abc

<script setup lang="ts">
const route = useRoute();
const userId = computed(() => route.params.id);
</script>

<template>
    <h1>Пользователь {{ userId }}</h1>
</template>

Несколько параметров

pages/users/[id]/posts/[postId].vue → /users/1/posts/5

<script setup lang="ts">
const route = useRoute();
const userId = route.params.id;
const postId = route.params.postId;
</script>

Вложенные (nested) роуты

Структура:

pages/
├── users/
│   ├── [id].vue
│   └── [id]/
│       ├── index.vue       → /users/1
│       ├── posts.vue       → /users/1/posts
│       └── settings.vue    → /users/1/settings

pages/users/[id].vue — родительский компонент:

<template>
    <div>
        <h1>Пользователь</h1>
        <nav>
            <NuxtLink :to="`/users/${$route.params.id}`">Профиль</NuxtLink>
            <NuxtLink :to="`/users/${$route.params.id}/posts`">Посты</NuxtLink>
        </nav>
        <NuxtPage />
    </div>
</template>

<NuxtPage /> — рендер дочерней страницы.

Опциональные параметры

[[param]] — двойные скобки.

pages/users/[[id]].vue → /users и /users/1

<script setup lang="ts">
const route = useRoute();
const id = computed(() => route.params.id);   // undefined или '1'
</script>

Catch-all

[...slug].vue — ловит всё.

pages/[...slug].vue → /a, /a/b, /a/b/c

<script setup lang="ts">
const route = useRoute();
const segments = route.params.slug;   // ['a', 'b', 'c']
</script>

<template>
    <h1>404 — {{ route.fullPath }}</h1>
</template>

Для 404 — pages/[...slug].vue в корне.

NuxtLink

Аналог RouterLink:

<NuxtLink to="/about">О нас</NuxtLink>
<NuxtLink :to="`/users/${user.id}`">{{ user.name }}</NuxtLink>
<NuxtLink :to="{ name: 'user-id', params: { id: 5 } }">Пользователь</NuxtLink>

Плюс: предзагрузка при наведении (prefetch).

Программная навигация

const router = useRouter();

await router.push('/about');
await router.push({ name: 'user-id', params: { id: 5 } });
await router.replace('/login');
router.back();

useRoute

const route = useRoute();

route.path;          // '/users/5'
route.params;        // { id: '5' }
route.query;         // { q: 'vue' }
route.name;          // имя роута
route.fullPath;      // '/users/5?q=vue'

Именованные роуты

По умолчанию имя = путь с дефисами.

pages/users/[id].vue → имя users-id.

Переопределить через definePageMeta:

<script setup lang="ts">
definePageMeta({
    name: 'user-profile',
});
</script>

Группы без URL

Скобки () — не влияют на URL.

pages/
├── (admin)/
│   ├── dashboard.vue       → /dashboard
│   └── users.vue           → /users
└── (public)/
    ├── index.vue           → /
    └── about.vue           → /about

Используется для группировки с общим layout или middleware.

Порядок маршрутов

Nuxt сортирует автоматически:

  • Статические (about.vue)
  • Динамические ([id].vue)
  • Catch-all ([...slug].vue)

Переопределить:

<script setup lang="ts">
definePageMeta({
    name: 'user-id',
});
</script>

Практика

Структура для блога:

pages/
├── index.vue                    → /
├── about.vue                    → /about
├── blog/
│   ├── index.vue                → /blog
│   ├── [slug].vue               → /blog/my-post
│   ├── category/
│   │   └── [category].vue       → /blog/category/vue
│   └── tag/
│       └── [tag].vue            → /blog/tag/vuejs
├── users/
│   ├── index.vue                → /users
│   └── [id]/
│       ├── index.vue            → /users/5
│       ├── posts.vue            → /users/5/posts
│       └── settings.vue         → /users/5/settings
└── [...slug].vue                → 404

NuxtPage с key

Для пересоздания при смене параметров:

<NuxtPage :key="$route.fullPath" />

По умолчанию компонент переиспользуется (как в Vue Router).

Итог

  • Структура pages/ = URL
  • [param] — динамика
  • [[param]] — опционально
  • [...slug] — catch-all
  • (group) — без URL
  • <NuxtLink> — навигация
  • <NuxtPage /> — вложенные

Дальше — динамические маршруты.