Урок 05

Vue Router: основы

Что такое Vue Router

Vue Router — официальный роутер для Vue. Позволяет переключать страницы без перезагрузки.

SPA (Single Page Application) — одно приложение, много «страниц».

Установка

Через create-vue:

npm create vue@latest my-app
# ✅ Vue Router

Вручную:

npm install vue-router@4

Настройка

src/router/index.js:

import { createRouter, createWebHistory } from 'vue-router';
import Home from '@/views/Home.vue';
import About from '@/views/About.vue';

const router = createRouter({
    history: createWebHistory(),
    routes: [
        { path: '/', name: 'home', component: Home },
        { path: '/about', name: 'about', component: About },
    ],
});

export default router;

main.js:

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

createApp(App).use(router).mount('#app');

App.vue

<template>
    <nav>
        <RouterLink to="/">Главная</RouterLink>
        <RouterLink to="/about">О нас</RouterLink>
    </nav>

    <RouterView />
</template>

<RouterView /> — место рендера текущего маршрута.

<RouterLink> — ссылка без перезагрузки.

Создание страниц

src/views/Home.vue:

<template>
    <h1>Главная</h1>
    <p>Добро пожаловать!</p>
</template>

src/views/About.vue:

<template>
    <h1>О нас</h1>
    <p>Мы делаем курсы.</p>
</template>

Правило: страницы в views/, компоненты в components/.

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

:id — параметр:

{ path: '/users/:id', name: 'user', component: User },

В компоненте:

<script setup>
import { useRoute } from 'vue-router';

const route = useRoute();
const userId = route.params.id;
</script>

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

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

{ path: '/users/:userId/posts/:postId', component: Post },
route.params.userId;
route.params.postId;

Необязательные параметры

{ path: '/users/:id?', component: User },

/users и /users/5 — оба работают.

Переходы

Через <RouterLink>:

<RouterLink to="/about">О нас</RouterLink>
<RouterLink :to="{ name: 'user', params: { id: 5 } }">Пользователь 5</RouterLink>
<RouterLink :to="{ path: '/about', query: { from: 'home' } }">О нас</RouterLink>

Программно:

import { useRouter } from 'vue-router';

const router = useRouter();

router.push('/about');
router.push({ name: 'user', params: { id: 5 } });
router.replace('/about');      // без истории
router.back();                 // назад
router.forward();              // вперёд
router.go(-1);                 // на 1 назад

Query-параметры

URL: /search?q=vue&page=2

route.query.q;      // 'vue'
route.query.page;   // '2'

Передать:

router.push({ path: '/search', query: { q: 'vue', page: 2 } });

Active-ссылки

<RouterLink
    to="/about"
    active-class="active"
    exact-active-class="exact-active"
>
    О нас
</RouterLink>

По умолчанию: router-link-active и router-link-exact-active.

Redirect и alias

{ path: '/home', redirect: '/' },
{ path: '/old', redirect: { name: 'home' } },
{ path: '/about', alias: '/info', component: About },

Catch-all 404

{ path: '/:pathMatch(.*)*', name: 'not-found', component: NotFound },

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

{ path: '/user/:id', name: 'user', component: User },
router.push({ name: 'user', params: { id: 5 } });

Плюс: не зависишь от URL.

Вложенные маршруты

{
    path: '/user/:id',
    component: User,
    children: [
        { path: '', name: 'user', component: UserProfile },
        { path: 'posts', component: UserPosts },
        { path: 'settings', component: UserSettings },
    ],
},

User.vue:

<template>
    <h1>Пользователь</h1>
    <nav>
        <RouterLink to=".">Профиль</RouterLink>
        <RouterLink to="posts">Посты</RouterLink>
        <RouterLink to="settings">Настройки</RouterLink>
    </nav>
    <RouterView />
</template>

URL: /user/5/posts, /user/5/settings.

Lazy loading

Загружать компонент только при переходе:

{
    path: '/about',
    component: () => import('@/views/About.vue'),
},

Плюс: меньше начальный бандл.

Meta-информация

{
    path: '/admin',
    component: Admin,
    meta: { requiresAuth: true, title: 'Админка' },
}

Доступ:

route.meta.title;

Доступ к route и router

<script setup>
import { useRoute, useRouter } from 'vue-router';

const route = useRoute();      // текущий маршрут (только чтение)
const router = useRouter();    // навигация

console.log(route.path);
console.log(route.params);
console.log(route.query);
console.log(route.name);

router.push('/');
</script>

Полный пример

src/router/index.js:

import { createRouter, createWebHistory } from 'vue-router';

const router = createRouter({
    history: createWebHistory(),
    routes: [
        { path: '/', name: 'home', component: () => import('@/views/Home.vue') },
        { path: '/about', name: 'about', component: () => import('@/views/About.vue') },
        { path: '/users', name: 'users', component: () => import('@/views/Users.vue') },
        {
            path: '/users/:id',
            name: 'user',
            component: () => import('@/views/User.vue'),
            children: [
                { path: '', name: 'user-profile', component: () => import('@/views/UserProfile.vue') },
                { path: 'posts', name: 'user-posts', component: () => import('@/views/UserPosts.vue') },
            ],
        },
        { path: '/:pathMatch(.*)*', name: 'not-found', component: () => import('@/views/NotFound.vue') },
    ],
});

export default router;

App.vue:

<template>
    <nav>
        <RouterLink to="/">Главная</RouterLink>
        <RouterLink to="/users">Пользователи</RouterLink>
        <RouterLink to="/about">О нас</RouterLink>
    </nav>

    <RouterView />
</template>

Итог

  • createRouter — создать роутер
  • RouterLink — ссылка без перезагрузки
  • RouterView — куда рендерить
  • Динамические маршруты — :id
  • Вложенные — children
  • Lazy loading — () => import(...)
  • useRoute / useRouter — доступ в компоненте

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