Vue
Параметры маршрутов и навигационные гварды
Магазину нужна одна страница товара, которая показывает товар по его идентификатору в URL: /product/42, /product/100 и так далее. Создавать отдельный маршрут на каждый товар немыслимо. Решение - динамический сегмент пути :id, который ловит любое значение и передаёт его компоненту. А раздел личного кабинета должен открываться только авторизованному пользователю - и тут вступают навигационные гварды, которые перехватывают переход до его завершения и решают, пускать или перенаправить на логин.
- Страница товара или профиля по идентификатору: один маршрут /product/:id обслуживает все товары
- Защита приватных разделов: гвард проверяет авторизацию и отправляет гостя на страницу входа
- Проверка прав по ролям: meta-флаг requiresAdmin и гвард, сверяющий роль пользователя
- Редирект устаревших URL: старый путь /old перенаправляется на новый без потери трафика
- Подтверждение ухода со страницы с несохранёнными изменениями через гвард на уровне компонента
Предварительные знания
- Создание роутера и конфигурация маршрутов из вводного урока
- useRoute для чтения данных текущего маршрута
- Понимание, что навигация в SPA асинхронна и проходит через роутер
Динамические параметры маршрута
Динамический сегмент объявляется двоеточием в пути: path: '/product/:id'. Такой маршрут совпадёт с /product/42 и /product/abc, а значение сегмента попадёт в route.params.id. Это превращает один маршрут в шаблон для тысяч страниц с одинаковой структурой.
Ключевой нюанс: при навигации между двумя экземплярами одного маршрута (тот же компонент, разный id) Vue Router переиспользует компонент, а не создаёт заново. Поэтому onMounted не сработает повторно, и реакцию на новый id нужно вешать через watch на route.params или передачу параметра как props с опцией props: true в маршруте.
props: true в маршруте передаёт route.params как props компонента. Это развязывает компонент от роутера: он принимает id как обычный проп и легче тестируется в отрыве от навигации.
При переходе с /product/42 на /product/100 данные не обновляются. В чём причина?
Навигационные гварды и meta
Гвард - это перехватчик навигации. Глобальный beforeEach выполняется перед каждым переходом и получает целевой маршрут to и исходный from. Возврат значения управляет переходом: true или ничего пускают навигацию, false отменяет её, а возврат объекта пути перенаправляет на другой маршрут. Это центральное место для проверки авторизации.
Поле meta хранит произвольные данные маршрута. Гвард читает их, чтобы понять правила доступа, не зашивая список приватных путей в свой код. Маршрут сам заявляет о своих требованиях через meta, а гвард остаётся универсальным.
Кроме глобального beforeEach есть гварды на уровне маршрута (beforeEnter в конфиге одного маршрута) и на уровне компонента (onBeforeRouteLeave для подтверждения ухода с несохранёнными данными). Глобальный проверяет общие правила, маршрутный - специфичные для одного пути, компонентный - связанные с состоянием конкретного экрана.
| Гвард | Уровень | Типичная задача |
|---|---|---|
| beforeEach | Глобальный | Авторизация, аналитика, общий контроль доступа |
| beforeEnter | Маршрут | Правило, специфичное для одного пути |
| onBeforeRouteLeave | Компонент | Подтверждение ухода с несохранёнными изменениями |
Как глобальный beforeEach должен перенаправить неавторизованного пользователя на логин?
Редиректы
Редирект отправляет один путь на другой. Самый прямой способ - поле redirect прямо в маршруте. Оно полезно для переезда URL (старый путь ведёт на новый) и для дефолтных перенаправлений (корень раздела открывает его первую страницу).
redirect принимает строку пути, объект именованного маршрута или функцию, которая получает целевой маршрут и возвращает назначение. Функциональная форма нужна, когда назначение зависит от параметров: старый /old/:id перенаправляется на /product/:id с сохранением идентификатора.
Редирект в конфиге маршрута и перенаправление из гварда решают разные задачи. Конфиг подходит для статичных правил, известных заранее (переезд URL). Гвард нужен, когда решение зависит от состояния во время выполнения (авторизован пользователь или нет).
Старый путь /old/:id нужно перенаправлять на /product/:id с тем же идентификатором. Как задать редирект?
Связь с другими темами
Урок развивает роутер до динамики и контроля навигации:
- Основы роутера — Параметры и гварды надстраиваются над конфигурацией маршрутов и useRoute
- Ленивая загрузка — Те же маршруты можно грузить по требованию через динамический import
- Pinia — Гварды авторизации читают состояние пользователя из стора
Итог
- Динамический сегмент пути вида /product/:id ловит любое значение, доступное в useRoute через route.params.id
- Смена только параметра не пересоздаёт компонент, поэтому реакцию на новый id ловят через watch на route.params или функцию props
- beforeEach - глобальный гвард, выполняемый перед каждой навигацией: возврат true пускает, false отменяет, объект пути перенаправляет
- Поле meta хранит произвольные метаданные маршрута, например requiresAuth, которые гвард читает для принятия решения
- Редирект задаётся полем redirect в маршруте или возвратом объекта пути из гварда
Связанные уроки
- vue-24-router-intro — Параметры и гварды строятся поверх конфигурации маршрутов и useRoute из вводного урока
- vue-26-lazy-routes — Ленивая загрузка применяется к тем же маршрутам, которые здесь получают параметры и гварды
- vue-27-pinia-intro — Гварды авторизации часто читают состояние пользователя из стора Pinia