Vue Front-end Инженер

Vue Front-end Инженер

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

Декларативная навигация

VueJSRouting (Vue Router)Основы

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

Декларативная навигация — это способ перехода между страницами в Vue Router с помощью компонента <router-link>. Вместо программного вызова router.push() разработчик описывает ссылку декларативно в шаблоне, а Vue Router обрабатывает переход.

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

  • router-link — компонент для создания навигационных ссылок
  • to — проп, указывающий целевой маршрут (строка или объект)
  • active-class — CSS-класс для активной ссылки
  • exact — точное совпадение пути для активного состояния
  • replace — заменяет текущую запись в истории вместо добавления

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

vue
<template>
  <!-- Строковый путь -->
  <router-link to="/about">О нас</router-link>
 
  <!-- Именованный маршрут -->
  <router-link :to="{ name: 'user', params: { id: 1 } }">
    Профиль
  </router-link>
 
  <!-- С query параметрами -->
  <router-link :to="{ path: '/search', query: { q: 'vue' } }">
    Поиск
  </router-link>
</template>

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

  • Забывают двоеточие :to при передаче объекта
  • Используют <a href> вместо <router-link> — теряется SPA-поведение
  • Путают params (для динамических сегментов) и query (для ?параметров)
  • Не учитывают, что params требуют именованного маршрута

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

  • Используйте router-link для всей внутренней навигации
  • Для внешних ссылок используйте обычный <a href>
  • Применяйте именованные маршруты — они устойчивы к изменению путей
  • Стилизуйте активные ссылки через router-link-active класс

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

В веб-приложениях навигация между страницами — одна из базовых задач. В обычных сайтах каждый переход требует перезагрузки страницы. В SPA (Single Page Application) навигация происходит без перезагрузки — меняется только контент. Vue Router предлагает два способа навигации: декларативный (через компоненты) и программный (через JavaScript).

Декларативная навигация — это использование компонента router-link в шаблоне для создания ссылок. Это предпочтительный способ для большинства случаев навигации в Vue-приложениях.


Базовая теория

router-link — это компонент Vue Router, который рендерится как тег <a>, но перехватывает клик и выполняет навигацию без перезагрузки страницы.

vue
<template>
  <nav>
    <router-link to="/">Главная</router-link>
    <router-link to="/about">О нас</router-link>
    <router-link to="/contact">Контакты</router-link>
  </nav>
</template>

Преимущества перед обычными ссылками


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

Строковый путь

Самый простой способ — передать путь как строку:

vue
<template>
  <router-link to="/users">Пользователи</router-link>
  <router-link to="/users/123">Пользователь 123</router-link>
  <router-link to="/search?q=vue">Поиск Vue</router-link>
</template>

Объект маршрута

Для более сложных случаев используйте объект с различными свойствами:

vue
<template>
  <!-- По имени маршрута -->
  <router-link :to="{ name: 'user-profile' }">
    Профиль
  </router-link>
 
  <!-- С параметрами пути -->
  <router-link :to="{ name: 'user', params: { id: 42 } }">
    Пользователь 42
  </router-link>
 
  <!-- С query параметрами -->
  <router-link :to="{ path: '/search', query: { q: 'vue', page: 1 } }">
    Поиск
  </router-link>
 
  <!-- С хэшем -->
  <router-link :to="{ path: '/docs', hash: '#installation' }">
    Установка
  </router-link>
</template>
⚠️

При использовании объекта с path нельзя использовать params. Параметры работают только с именованными маршрутами (name). Query-параметры работают с обоими вариантами.


Основные props

vue
<template>
  <!-- to — целевой маршрут (обязательный) -->
  <router-link to="/about">О нас</router-link>
 
  <!-- replace — заменить запись в истории -->
  <router-link to="/login" replace>Войти</router-link>
 
  <!-- active-class — класс для активной ссылки -->
  <router-link to="/home" active-class="is-active">
    Главная
  </router-link>
 
  <!-- exact-active-class — класс для точного совпадения -->
  <router-link to="/" exact-active-class="exact-active">
    Главная
  </router-link>
</template>

Prop custom и слот по умолчанию

С Vue Router 4 можно использовать слот для полного контроля над рендерингом:

vue
<template>
  <router-link to="/about" custom v-slot="{ navigate, isActive, href }">
    <button
      @click="navigate"
      :class="{ active: isActive }"
    >
      О нас
    </button>
  </router-link>
</template>

Слот предоставляет:

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

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

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

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

Настройка классов глобально

js
const router = createRouter({
  history: createWebHistory(),
  routes,
  linkActiveClass: 'is-active',
  linkExactActiveClass: 'is-exact-active'
})

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

Навигационное меню

vue
<script setup>
import { RouterLink } from 'vue-router'
 
const menuItems = [
  { name: 'home', label: 'Главная', path: '/' },
  { name: 'catalog', label: 'Каталог', path: '/catalog' },
  { name: 'cart', label: 'Корзина', path: '/cart' },
  { name: 'profile', label: 'Профиль', path: '/profile' }
]
</script>
 
<template>
  <nav class="main-nav">
    <RouterLink
      v-for="item in menuItems"
      :key="item.name"
      :to="item.path"
      class="nav-link"
    >
      {{ item.label }}
    </RouterLink>
  </nav>
</template>
 
<style scoped>
.main-nav {
  display: flex;
  gap: 1rem;
}
 
.nav-link {
  padding: 0.5rem 1rem;
  text-decoration: none;
  color: #333;
  border-radius: 4px;
}
 
.nav-link.router-link-active {
  background: #e0e0e0;
}
 
.nav-link.router-link-exact-active {
  background: #007bff;
  color: white;
}
</style>

Навигация с параметрами

vue
<script setup>
const users = [
  { id: 1, name: 'Анна' },
  { id: 2, name: 'Борис' },
  { id: 3, name: 'Виктор' }
]
</script>
 
<template>
  <ul>
    <li v-for="user in users" :key="user.id">
      <router-link :to="{ name: 'user', params: { id: user.id } }">
        {{ user.name }}
      </router-link>
    </li>
  </ul>
</template>

Декларативная vs Программная навигация

АспектДекларативнаяПрограммная
Синтаксис<router-link to="...">router.push(...)
ИспользованиеВ шаблонеВ JavaScript
Случаи примененияОбычные ссылкиПосле событий, в логике
Активные классыАвтоматическиВручную
vue
<script setup>
import { useRouter } from 'vue-router'
 
const router = useRouter()
 
function handleLogin() {
  // Программная навигация после успешного входа
  router.push('/dashboard')
}
</script>
 
<template>
  <!-- Декларативная навигация для обычных ссылок -->
  <router-link to="/register">Регистрация</router-link>
 
  <!-- Программная навигация после действия -->
  <button @click="handleLogin">Войти</button>
</template>

Пограничные кейсы

Внешние ссылки

Для внешних URL используйте обычный тег <a>:

vue
<template>
  <!-- Внутренняя навигация -->
  <router-link to="/about">О нас</router-link>
 
  <!-- Внешняя ссылка -->
  <a href="https://vuejs.org" target="_blank" rel="noopener">
    Vue.js
  </a>
</template>

Отключённые ссылки

vue
<script setup>
import { ref } from 'vue'
 
const isDisabled = ref(true)
</script>
 
<template>
  <router-link
    to="/checkout"
    custom
    v-slot="{ navigate }"
  >
    <button
      @click="navigate"
      :disabled="isDisabled"
    >
      Оформить заказ
    </button>
  </router-link>
</template>

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

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

router-link перехватывает клик и выполняет навигацию без перезагрузки страницы. Также он автоматически добавляет CSS-классы для активного состояния.

Q: Как передать параметры в router-link?

Через объект: :to="{ name: 'route-name', params: { id: 1 }, query: { sort: 'asc' } }". Params работают только с именованными маршрутами.

Q: Какие CSS-классы добавляются активным ссылкам?

router-link-active для частичного совпадения пути и router-link-exact-active для точного совпадения.

Q: Когда использовать декларативную, а когда программную навигацию?

Декларативную — для обычных ссылок в UI. Программную — для навигации в ответ на события (после формы, по таймеру, в условной логике).


Источники