Олег Марков
Использование router-link для навигации в Vue Router
Введение
Навигация — одна из ключевых задач современных одностраничных приложений. Именно она задает логику перехода между страницами и определяет, как пользователь перемещается внутри проекта. Во Vue.js для этих целей чаще всего применяют Vue Router — официальный маршрутизатор фреймворка. Базовым инструментом для построения навигации в нем служит элемент router-link.
router-link — это не обычная ссылка из HTML. Она интегрирована с системой маршрутов, работает без перезагрузки страницы, корректно обновляет адресную строку и под капотом использует API истории браузера. В этой статье вы разберетесь, как использовать router-link на практике, познакомитесь с его свойствами, увидите различные сценарии его применения и получите ответы на частые вопросы о его работе.
router-link — базовый инструмент навигации
Основные задачи и преимущества
Элемент router-link предназначен для создания ссылок, которые адаптируются под вашу конфигурацию маршрутов. Его использование гарантирует корректный переход между компонентами без перезагрузки страницы.
Преимущества router-link по сравнению с обычной ссылкой:
- Интеграция с маршрутизатором — автоматически использует вашу конфигурацию маршрутов;
- Без перезагрузки страницы — работает как SPA (Single Page Application);
- Реактивность — ссылки автоматически отражают состояние активного маршрута;
- Дополнительные возможности — задаете параметры, переходите программно, работает prefetching.
Теперь посмотрим, как этот инструмент применяется на практике.
Простейший пример использования
Вот минимальный пример router-link внутри компонента:
<template>
<router-link to="/about">О проекте</router-link>
</template>
// Этот код создает ссылку, ведущую на путь "/about" // По клику компонент, связанный с этим маршрутом, отрисуется без перезагрузки страницы
Такой подход позволит пользователю плавно и почти незаметно для себя переходить между страницами приложения.
Свойство to — выбор маршрута
Самое важное свойство router-link — это to
. Именно оно определяет, на какой путь будет вести ссылка.
Передача строки
Чаще всего to
принимает строку пути:
<router-link to="/dashboard">Панель управления</router-link>
// При клике происходит переход на /dashboard
Использование объекта (route location object)
Вы также можете прокидывать объект с названием маршрута и параметрами:
<router-link :to="{ name: 'user', params: { userId: 10 } }">Профиль</router-link>
// Здесь name ссылается на название маршрута из конфигурации Vue Router // params позволит подставить параметры прямо в путь, например /user/10
Обратите внимание, если вы используете параметры, необходимо чтобы путь маршрута содержал, например, "/user/:userId".
Динамическое вычисление значения to
router-link прекрасно работает с реактивными переменными и computed:
<script setup>
import { ref } from 'vue'
const userId = ref(15)
</script>
<template>
<router-link :to="`/user/${userId}`">Мой профиль</router-link>
</template>
// userId может измениться, и ссылка всегда будет вести на актуальный путь
Такой подход очень удобен для динамической навигации.
Настройка внешнего вида и поведения
router-link позволяет настраивать как внешний вид, так и поведение ссылки.
tag — какой элемент рендерить
По умолчанию router-link отображается как тег <a>
. Если вам нужно изменить его на любой другой тег (например, <li>
), используйте пропс tag
:
<router-link to="/contacts" tag="li">Контакты</router-link>
// Рендер будет через
, событие клика все равно останется на месте // Учтите, что начиная с Vue Router 4 данный пропс больше не поддерживается; используйте scoped slotsscoped slot — кастомизация содержимого (Vue Router 4+)
Теперь для управления вложенным содержимым используют слот с деструктуризацией:
<router-link to="/news" v-slot="{ href, navigate, isActive, isExactActive }">
<li :class="{ active: isActive }">
<a :href="href" @click="navigate">Новости</a>
</li>
</router-link>
// Такой подход дает полный контроль над рендерингом и стилем активной ссылки
Кастомизация классов: active-class и exact-active-class
Cоздавая навигацию, вы хотите подчеркнуть, какая страница активна. Для этого router-link использует специальные классы:
router-link-active
— назначается, если ссылка совпадает с текущим маршрутом по вложенности;router-link-exact-active
— применяется только при полном совпадении path.
Вы можете задать свои классы с помощью свойств:
<router-link
to="/about"
active-class="is-current"
exact-active-class="is-exact"
>
О сайте
</router-link>
// Класс is-current появится при частичном совпадении, is-exact — только когда путь совпадает полностью
Это полезно, если в вашем CSS уже есть дизайнерские классы для активных пунктов меню.
Переходы со специфическим поведением
Переход с добавлением (append)
Иногда необходимо делать переход относительным, зацепившись за текущий путь:
<router-link :to="{ path: 'settings' }" append>Настройки</router-link>
// Если вы сейчас на /user, ссылка ведет на /user/settings, а не на /settings
Параметры query и hash
router-link может вести не только на путь, но и на путь с query-параметрами или якорями:
<router-link :to="{ path: '/posts', query: { sort: 'date' }, hash: '#top' }">
Сортировать по дате
</router-link>
// В адресной строке будет /posts?sort=date#top // Это удобно для фильтров, сортировок, внутренних якорей
router-link и маршрутизация: как работает под капотом
Когда вы используете router-link, на самом деле происходит:
- Элемент
<a>
получает специальный обработчик клика вместо обычного перехода; - Клик вызывает межеуровневую функцию Vue Router, которая обновляет адресную строку через history.pushState (или hash, если роутер настроен так);
- Приложение реагирует на изменение маршрута, загружая нужный компонент;
- Страница не перезагружается — обновляется только контент.
Благодаря этому эффекту вы получаете быстро работающую SPA-навигацию, SEO-friendly при правильной настройке, и хорошую интеграцию с devtools.
Деактивация router-link
Иногда нужно сделать ссылку неактивной (например, в случае disabled состояния). Важно понимать: router-link сам по себе не предоставляет prop disabled, как обычная кнопка. Однако вы можете реализовать эту логику самостоятельно:
<template>
<router-link
:to="isAllowed ? '/admin' : ''"
:tabindex="isAllowed ? 0 : -1"
:aria-disabled="!isAllowed"
:class="{ disabled: !isAllowed }"
@click.prevent="!isAllowed"
>
Админ-панель
</router-link>
</template>
// Переменная isAllowed управляет доступом
// Событие @click.prevent предотвращает нежелательные переходы
Добавьте стили для disabled, если требуется.
Навигация в шаблонных циклах
Очень частый случай — строить списки меню или галерей, используя router-link внутри v-for:
<template>
<nav>
<ul>
<li v-for="item in menuItems" :key="item.id">
<router-link :to="item.path">{{ item.title }}</router-link>
</li>
</ul>
</nav>
</template>
// menuItems массив с путями и названиями пунктов меню
// Такая структура улучшает читаемость и масштабируемость кода
Альтернативы router-link: навигация программно
Часто нужно переводить пользователя на другой маршрут не ссылкой, а программно (например, в результате запроса или после действия). Для этого используется router.push:
// Импортируйте useRouter из 'vue-router' (работает в setup)
import { useRouter } from 'vue-router'
const router = useRouter()
function goToProfile() {
router.push('/profile') // или объект с именем маршрута и параметрами
}
// Такой способ удобен для кнопок, сабмитов форм и т.д.
router-link же ориентирован именно на declarative-навигацию — то есть когда переход происходит по клику на ссылку.
Использование router-link в мобильных и PWA-приложениях
Docker-link одинаково хорошо работает и на десктопных браузерах, и в мобильных приложениях, построенных на основе Vue.js (например, с использованием frameworks типа Quasar или Vuetify). В PWA-приложениях поведение аналогично: SPA-переходы работают мгновенно, не грузят сервер, ссылки получают доступность для ассистивных технологий.
Советы по оптимизации работы router-link
- Всегда используйте router-link вместо обычных
<a>
для внутренних переходов. Это обеспечивает синхронизацию истории браузера и корректную работу Vue Router. - Если нужно перейти на внешний ресурс, не используйте router-link — используйте обычный
<a href="...">
. - Для SEO и SSR используйте meta-теги, prerendering, чтобы поисковики корректно сканировали ссылки.
- Следите, чтобы ваши параметры маршрутов совпадали с конфигом роутера (например, путь должен содержать :userId, если вы передаете params).
Заключение
router-link — универсальный компонент Vue Router, который обеспечивает современную, удобную и реактивную навигацию в вашем приложении на Vue.js. Он снимает множество забот по синхронизации истории, визуальному оформлению активных страниц и поддержке сложных маршрутов с параметрами, query, hash и префиксами. Его удобно использовать как частью навигации в шапке, так и для сложных, вложенных меню, динамических и условных переходов. Освоив его, вы сможете существенно улучшить пользовательский опыт вашего приложения и поддерживать навигацию на профессиональном уровне.
Частозадаваемые технические вопросы и ответы
Как использовать router-link для внешних URL?
router-link предназначен только для внутренних маршрутов, управляемых Vue Router. Для внешних адресов используйте обычный тег <a>
с target="_blank" или target="_self":
<a href="https://example.com" target="_blank" rel="noopener">Открыть сайт</a>
Как сделать router-link с preventDefault только для определённых условий?
Вешайте обработчик @click с условием и вызовом event.preventDefault()
вручную:
<router-link :to="someRoute" @click="someCondition && $event.preventDefault()">
Линк
</router-link>
Как изменить элемент, который рендерит router-link, в Vue Router 4?
Начиная с Vue Router 4, вместо свойства tag
используйте scoped slot для полного контроля над рендером:
<router-link to="/path" v-slot="{ href, navigate }">
<li @click="navigate"><a :href="href">Ссылка</a></li>
</router-link>
Почему не срабатывает активный класс у router-link?
Проверьте, совпадает ли точное значение to
с текущим путем, а также не задали ли вы свой active-class
или exact-active-class
. Если используете именованный маршрут, убедитесь что params корректны.
Как стилизовать router-link как кнопку?
Router-link принимает любые стили, поэтому вы можете добавить класс или использовать scoped slot для рендера кнопки:
<router-link to="/submit">
<button class="btn">Отправить</button>
</router-link>
// При таком оформлении сохраняется SPA-навигация, а внешний вид — как у кнопки