Vue Front-end Инженер

Vue Front-end Инженер

Роадмап навыков для прокачки

RouterView / RouterLink

VueJSRouting (Vue Router)Основы

Основная идея

RouterView и RouterLink — два основных компонента Vue Router. RouterView определяет место в шаблоне, где будет отображаться компонент текущего маршрута. RouterLink создаёт навигационные ссылки, которые работают без перезагрузки страницы.

Ключевые аспекты

  • RouterView — компонент-плейсхолдер для отображения маршрутов
  • RouterLink — компонент для создания SPA-ссылок
  • to — проп RouterLink для указания целевого маршрута
  • name — проп RouterView для именованных представлений
  • v-slot — доступ к данным маршрута и компоненту

Базовый синтаксис

vue
<script setup>
import { RouterView, RouterLink } from 'vue-router'
</script>
 
<template>
  <nav>
    <RouterLink to="/">Главная</RouterLink>
    <RouterLink to="/about">О нас</RouterLink>
  </nav>
 
  <main>
    <RouterView />
  </main>
</template>

Частые ошибки

  • Забывают добавить RouterView — компоненты маршрутов не отображаются
  • Используют <a href> вместо RouterLink — теряется SPA-поведение
  • Размещают несколько RouterView без именования — конфликты отображения
  • Не импортируют компоненты в script setup при использовании PascalCase

Рекомендации

  • Используйте RouterView как точку входа для страниц приложения
  • RouterLink предпочтительнее программной навигации для обычных ссылок
  • Для сложных layout применяйте именованные RouterView
  • Используйте v-slot для анимаций переходов между страницами
  • Импортируйте компоненты явно для лучшей читаемости кода

Введение и проблематика

Vue Router предоставляет два ключевых компонента для работы с маршрутизацией: RouterView и RouterLink. Без понимания этих компонентов невозможно построить навигацию в Vue-приложении. RouterView определяет, где отображать содержимое маршрута, а RouterLink обеспечивает переходы между страницами.

RouterView и RouterLink работают в паре: RouterLink указывает куда перейти, а RouterView показывает что отобразить. Это основа всей навигации в Vue-приложениях.


RouterView — отображение маршрутов

Базовое использование

RouterView — это компонент-плейсхолдер. Vue Router рендерит в него компонент, соответствующий текущему URL:

vue
<script setup>
import { RouterView } from 'vue-router'
</script>
 
<template>
  <header>Шапка сайта</header>
 
  <!-- Сюда будет рендериться компонент текущего маршрута -->
  <RouterView />
 
  <footer>Подвал сайта</footer>
</template>

Как это работает

js
// router/index.js
const routes = [
  { path: '/', component: HomePage },      // URL: / → HomePage
  { path: '/about', component: AboutPage }, // URL: /about → AboutPage
  { path: '/contact', component: ContactPage }
]

При переходе на /about Vue Router найдёт соответствующий маршрут и отрендерит AboutPage внутри <RouterView />.

Props компонента RouterView

vue
<template>
  <!-- Базовый RouterView -->
  <RouterView />
 
  <!-- Именованный RouterView -->
  <RouterView name="sidebar" />
 
  <!-- С передачей props в компонент маршрута -->
  <RouterView :route="customRoute" />
</template>

Базовое использование

RouterLink создаёт ссылки, которые перехватывают клик и выполняют навигацию без перезагрузки страницы:

vue
<script setup>
import { RouterLink } from 'vue-router'
</script>
 
<template>
  <nav>
    <RouterLink to="/">Главная</RouterLink>
    <RouterLink to="/about">О нас</RouterLink>
    <RouterLink to="/contact">Контакты</RouterLink>
  </nav>
</template>

Способы указания маршрута

vue
<template>
  <!-- Простой путь -->
  <RouterLink to="/users">Пользователи</RouterLink>
 
  <!-- С query параметрами -->
  <RouterLink to="/search?q=vue">Поиск</RouterLink>
</template>
  • Простой синтаксис
  • Подходит для статических путей
  • Легко читается
vue
<template>
  <!-- Основной проп — целевой маршрут -->
  <RouterLink to="/about">О нас</RouterLink>
 
  <!-- Заменить запись в истории (без возврата назад) -->
  <RouterLink to="/login" replace>Войти</RouterLink>
 
  <!-- Кастомный класс для активной ссылки -->
  <RouterLink to="/home" active-class="active">
    Главная
  </RouterLink>
 
  <!-- Класс для точного совпадения -->
  <RouterLink to="/" exact-active-class="exact">
    Главная
  </RouterLink>
</template>

Совместное использование

Типичная структура приложения

vue
<!-- App.vue -->
<script setup>
import { RouterView, RouterLink } from 'vue-router'
</script>
 
<template>
  <div class="app">
    <header>
      <nav>
        <RouterLink to="/">Главная</RouterLink>
        <RouterLink to="/catalog">Каталог</RouterLink>
        <RouterLink to="/cart">Корзина</RouterLink>
      </nav>
    </header>
 
    <main>
      <RouterView />
    </main>
 
    <footer>
      <p>© 2024 Мой магазин</p>
    </footer>
  </div>
</template>

Конфигурация роутера

js
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import HomePage from '@/views/HomePage.vue'
import CatalogPage from '@/views/CatalogPage.vue'
import CartPage from '@/views/CartPage.vue'
 
const routes = [
  { path: '/', name: 'home', component: HomePage },
  { path: '/catalog', name: 'catalog', component: CatalogPage },
  { path: '/cart', name: 'cart', component: CartPage }
]
 
const router = createRouter({
  history: createWebHistory(),
  routes
})
 
export default router

Продвинутые возможности

RouterView с v-slot

v-slot даёт доступ к компоненту маршрута и позволяет добавлять анимации:

vue
<template>
  <RouterView v-slot="{ Component, route }">
    <transition name="fade" mode="out-in">
      <component
        :is="Component"
        :key="route.path"
      />
    </transition>
  </RouterView>
</template>
 
<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}
 
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

v-slot позволяет полностью контролировать рендеринг ссылки:

vue
<template>
  <RouterLink
    to="/dashboard"
    custom
    v-slot="{ navigate, href, isActive, isExactActive }"
  >
    <a
      :href="href"
      @click="navigate"
      :class="{
        'is-active': isActive,
        'is-exact': isExactActive
      }"
    >
      Панель управления
    </a>
  </RouterLink>
</template>

Доступные свойства в слоте:

  • href — сформированный URL
  • navigate — функция для перехода
  • isActive — активен ли маршрут (включая вложенные)
  • isExactActive — точное совпадение маршрута
  • route — объект целевого маршрута

Именованные RouterView

Для сложных layout можно использовать несколько RouterView:

vue
<!-- App.vue -->
<template>
  <div class="layout">
    <RouterView name="header" />
 
    <div class="content">
      <RouterView name="sidebar" />
      <RouterView /> <!-- default -->
    </div>
 
    <RouterView name="footer" />
  </div>
</template>
js
// router/index.js
const routes = [
  {
    path: '/',
    components: {
      default: MainContent,
      header: HeaderComponent,
      sidebar: SidebarComponent,
      footer: FooterComponent
    }
  }
]

Активные классы ссылок

Vue Router автоматически добавляет CSS-классы активным ссылкам:

vue
<template>
  <nav>
    <!-- При URL /users/123 -->
    <!-- Получит router-link-active (частичное совпадение) -->
    <RouterLink to="/users">Пользователи</RouterLink>
 
    <!-- Получит оба класса (точное совпадение) -->
    <RouterLink to="/users/123">User 123</RouterLink>
  </nav>
</template>
 
<style>
/* Частичное совпадение пути */
.router-link-active {
  font-weight: bold;
}
 
/* Точное совпадение URL */
.router-link-exact-active {
  color: #42b983;
}
</style>

Практический пример

Навигация интернет-магазина

vue
<script setup>
import { RouterView, RouterLink } from 'vue-router'
import { computed } from 'vue'
import { useCartStore } from '@/stores/cart'
 
const cart = useCartStore()
const cartCount = computed(() => cart.items.length)
</script>
 
<template>
  <div class="shop-layout">
    <header class="header">
      <RouterLink to="/" class="logo">
        Магазин
      </RouterLink>
 
      <nav class="nav">
        <RouterLink to="/catalog" class="nav-link">
          Каталог
        </RouterLink>
        <RouterLink to="/sales" class="nav-link">
          Акции
        </RouterLink>
        <RouterLink to="/cart" class="nav-link cart-link">
          Корзина
          <span v-if="cartCount" class="badge">
            {{ cartCount }}
          </span>
        </RouterLink>
      </nav>
    </header>
 
    <main class="main">
      <RouterView />
    </main>
  </div>
</template>
 
<style scoped>
.nav-link {
  padding: 0.5rem 1rem;
  text-decoration: none;
  color: #333;
}
 
.nav-link.router-link-active {
  background: #f0f0f0;
  border-radius: 4px;
}
 
.badge {
  background: #e74c3c;
  color: white;
  border-radius: 50%;
  padding: 2px 8px;
  font-size: 12px;
}
</style>

Сравнение kebab-case и PascalCase

Оба варианта работают одинаково:

vue
<template>
  <!-- kebab-case (автоматически доступны) -->
  <router-view />
  <router-link to="/">Главная</router-link>
 
  <!-- PascalCase (требуют импорта) -->
  <RouterView />
  <RouterLink to="/">Главная</RouterLink>
</template>

При использовании script setup рекомендуется PascalCase с явным импортом — это обеспечивает лучшую поддержку TypeScript и tree-shaking.


Вопросы интервьюера

Q: Что такое RouterView?

Компонент-плейсхолдер, который отображает компонент текущего маршрута. Определяет место в шаблоне, где будет рендериться содержимое страницы.

Q: Чем RouterLink отличается от обычной ссылки?

RouterLink перехватывает клик и выполняет навигацию без перезагрузки страницы, сохраняя состояние SPA. Также автоматически добавляет классы для активного состояния.

Q: Как добавить анимацию переходов между страницами?

Использовать v-slot на RouterView для доступа к компоненту и обернуть его в <transition>.

Q: Можно ли использовать несколько RouterView на странице?

Да, с помощью именованных RouterView (проп name) и указания components вместо component в конфигурации маршрута.


Источники