
Vue Router: маршрутизация
Vue Router — это официальная библиотека маршрутизации для Vue.js, которая позволяет создавать одностраничные приложения (SPA) с множественными представлениями. Она обеспечивает навигацию между компонентами без перезагрузки страницы, сохраняя состояние приложения и обеспечивая плавный пользовательский опыт.
Vue Router интегрируется с экосистемой Vue.js и предоставляет мощные возможности для управления маршрутами, включая вложенные маршруты, защищенные маршруты, ленивую загрузку компонентов и многое другое.
1. Установка и настройка Vue Router
Установка
Vue Router можно установить несколькими способами. Если вы используете Vue CLI, то при создании проекта выберите опцию Router. Для существующих проектов установите пакет через npm:
npm install vue-router@4
Примечание: Vue Router 4 совместим с Vue 3, а Vue Router 3 — с Vue 2. Убедитесь, что используете правильную версию.
Базовая настройка
Создайте файл router/index.js
в вашем проекте:
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
Интеграция с приложением
В главном файле main.js
подключите роутер:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')
Использование в App.vue
В корневом компоненте добавьте <router-view>
для отображения компонентов маршрутов:
<template>
<div id="app">
<nav>
<router-link to="/">Главная</router-link> |
<router-link to="/about">О нас</router-link>
</nav>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
2. Основные концепции маршрутизации
Router-Link
<router-link>
— это компонент для навигации между маршрутами. Он автоматически генерирует правильные ссылки и обрабатывает клики:
<template>
<div>
<!-- Базовое использование -->
<router-link to="/home">Главная</router-link>
<!-- С именованным маршрутом -->
<router-link :to="{ name: 'user', params: { id: 123 }}">
Профиль пользователя
</router-link>
<!-- С query параметрами -->
<router-link :to="{ path: '/search', query: { q: 'vue' }}">
Поиск
</router-link>
<!-- С активным классом -->
<router-link to="/about" active-class="active-link">
О нас
</router-link>
</div>
</template>
Router-View
<router-view>
— это компонент, который отображает компонент, соответствующий текущему маршруту:
<template>
<div>
<!-- Основной контент -->
<router-view />
<!-- Именованные представления -->
<router-view name="sidebar" />
<router-view name="footer" />
</div>
</template>
Программная навигация
Для программной навигации используйте методы роутера в компонентах:
export default {
methods: {
goToHome() {
this.$router.push('/')
},
goToUser(id) {
this.$router.push({ name: 'user', params: { id } })
},
goBack() {
this.$router.go(-1)
},
replaceRoute() {
this.$router.replace('/new-route')
}
}
}
3. Типы маршрутов
Статические маршруты
Самый простой тип маршрутов — статические пути:
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
},
{
path: '/contact',
name: 'Contact',
component: Contact
}
]
Динамические маршруты
Для маршрутов с параметрами используйте двоеточие:
const routes = [
{
path: '/user/:id',
name: 'User',
component: User
},
{
path: '/post/:category/:id',
name: 'Post',
component: Post
}
]
В компоненте доступ к параметрам осуществляется через $route.params
:
<template>
<div>
<h1>Пользователь {{ $route.params.id }}</h1>
</div>
</template>
<script>
export default {
name: 'User',
created() {
console.log('ID пользователя:', this.$route.params.id)
}
}
</script>
Вложенные маршруты
Вложенные маршруты позволяют создавать сложную структуру навигации:
const routes = [
{
path: '/user/:id',
component: UserLayout,
children: [
{
path: '',
name: 'UserProfile',
component: UserProfile
},
{
path: 'posts',
name: 'UserPosts',
component: UserPosts
},
{
path: 'settings',
name: 'UserSettings',
component: UserSettings
}
]
}
]
В родительском компоненте UserLayout.vue
добавьте <router-view>
:
<template>
<div class="user-layout">
<nav class="user-nav">
<router-link to="/user/123">Профиль</router-link>
<router-link to="/user/123/posts">Посты</router-link>
<router-link to="/user/123/settings">Настройки</router-link>
</nav>
<div class="user-content">
<router-view />
</div>
</div>
</template>
Именованные маршруты
Именованные маршруты упрощают навигацию и делают код более читаемым:
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/user/:id',
name: 'User',
component: User
}
]
Использование:
// Вместо this.$router.push('/user/123')
this.$router.push({ name: 'User', params: { id: 123 } })
// В template
<router-link :to="{ name: 'User', params: { id: 123 }}">
Профиль пользователя
</router-link>
4. Продвинутые возможности
Ленивая загрузка компонентов
Для оптимизации производительности используйте ленивую загрузку:
const routes = [
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
},
{
path: '/dashboard',
name: 'Dashboard',
component: () => import('../views/Dashboard.vue')
}
]
Защищенные маршруты
Реализуйте защиту маршрутов с помощью навигационных стражей:
const routes = [
{
path: '/admin',
name: 'Admin',
component: Admin,
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: '/profile',
name: 'Profile',
component: Profile,
meta: { requiresAuth: true }
}
]
router.beforeEach((to, from, next) => {
const isAuthenticated = checkAuthStatus()
const isAdmin = checkAdminStatus()
if (to.meta.requiresAuth && !isAuthenticated) {
next('/login')
} else if (to.meta.requiresAdmin && !isAdmin) {
next('/forbidden')
} else {
next()
}
})
Перехватчики навигации
Используйте перехватчики для выполнения действий при навигации:
router.beforeEach((to, from, next) => {
// Показать индикатор загрузки
showLoading()
next()
})
router.afterEach((to, from) => {
// Скрыть индикатор загрузки
hideLoading()
// Отправить аналитику
trackPageView(to.path)
})
Query параметры
Работа с query параметрами:
// В компоненте
export default {
methods: {
updateQuery() {
this.$router.push({
query: {
...this.$route.query,
page: 2,
sort: 'name'
}
})
}
},
computed: {
currentPage() {
return parseInt(this.$route.query.page) || 1
},
sortBy() {
return this.$route.query.sort || 'id'
}
}
}
5. Практические примеры
Пример приложения блога
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{
path: '/',
name: 'Home',
component: () => import('../views/Home.vue')
},
{
path: '/blog',
name: 'Blog',
component: () => import('../views/Blog.vue'),
children: [
{
path: '',
name: 'BlogList',
component: () => import('../views/BlogList.vue')
},
{
path: ':id',
name: 'BlogPost',
component: () => import('../views/BlogPost.vue'),
props: true
}
]
},
{
path: '/login',
name: 'Login',
component: () => import('../views/Login.vue')
},
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: () => import('../views/NotFound.vue')
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
Компонент навигации
<template>
<nav class="navbar">
<div class="nav-brand">
<router-link to="/">Мой блог</router-link>
</div>
<div class="nav-links">
<router-link to="/" exact-active-class="active">
Главная
</router-link>
<router-link to="/blog" active-class="active">
Блог
</router-link>
<router-link v-if="!isAuthenticated" to="/login">
Войти
</router-link>
<a v-else @click="logout" href="#">Выйти</a>
</div>
</nav>
</template>
<script>
export default {
name: 'Navbar',
computed: {
isAuthenticated() {
return this.$store.state.auth.isAuthenticated
}
},
methods: {
logout() {
this.$store.dispatch('auth/logout')
this.$router.push('/login')
}
}
}
</script>
6. Лучшие практики
Организация файлов
src/
├── router/
│ ├── index.js # Основная конфигурация
│ ├── routes/ # Отдельные файлы маршрутов
│ │ ├── auth.js
│ │ ├── blog.js
│ │ └── admin.js
│ └── guards.js # Навигационные стражы
├── views/ # Компоненты страниц
│ ├── Home.vue
│ ├── Blog.vue
│ └── Admin.vue
└── components/ # Переиспользуемые компоненты
├── Navbar.vue
└── Footer.vue
Разделение маршрутов
// router/routes/blog.js
export default [
{
path: '/blog',
name: 'Blog',
component: () => import('@/views/Blog.vue'),
children: [
{
path: '',
name: 'BlogList',
component: () => import('@/views/BlogList.vue')
},
{
path: ':id',
name: 'BlogPost',
component: () => import('@/views/BlogPost.vue'),
props: true
}
]
}
]
// router/index.js
import blogRoutes from './routes/blog.js'
const routes = [
...blogRoutes,
// другие маршруты
]
Обработка ошибок
router.onError((error) => {
if (error.name === 'ChunkLoadError') {
// Ошибка загрузки компонента
router.push('/error')
}
})
7. Отладка и инструменты
Vue DevTools
Установите Vue DevTools для отладки маршрутизации:
# Chrome
npm install -g @vue/devtools
# Или через расширение браузера
Логирование
Добавьте логирование для отладки:
router.beforeEach((to, from, next) => {
console.log(`Навигация: ${from.path} → ${to.path}`)
console.log('Параметры:', to.params)
console.log('Query:', to.query)
next()
})
Заключение
Vue Router предоставляет мощную и гибкую систему маршрутизации для Vue.js приложений. Он позволяет создавать сложные SPA с множественными представлениями, защищенными маршрутами и оптимизированной производительностью.
Основные преимущества Vue Router:
- Простота использования — интуитивный API и хорошая документация
- Гибкость — поддержка различных типов маршрутов и навигации
- Производительность — ленивая загрузка и оптимизация
- Интеграция — тесная интеграция с экосистемой Vue.js
- Расширяемость — возможность создания собственных плагинов и расширений
При правильном использовании Vue Router значительно упрощает разработку сложных веб-приложений и улучшает пользовательский опыт.