# Динамические пути
Очень часто нам требуется сопоставить маршруты с заданным шаблоном с одним и тем же компонентом. Например, у нас может быть компонент User
, который должен отображаться для всех пользователей, но с разными ID пользователей. Во vue-router
мы можем использовать динамический сегмент в маршруте, чтобы достичь этого:
const User = {
template: '<div>Пользователь</div>'
}
const router = new VueRouter({
routes: [
// динамические сегменты начинаются с двоеточия
{ path: '/user/:id', component: User }
]
})
Теперь все URL вида /user/foo
и /user/bar
будут соответствовать одному маршруту.
Динамический сегмент обозначается двоеточием :
. При сопоставлении маршрута, значение динамического сегмента можно получить через this.$route.params
в каждом компоненте. Теперь мы можем отобразить ID текущего пользователя, обновив шаблон компонента User
:
const User = {
template: '<div>Пользователь {{ $route.params.id }}</div>'
}
Вы можете посмотреть этот пример вживую здесь (opens new window).
Может быть несколько динамических сегментов в одном маршруте. Для каждого сегмента появится соответствующее свойство в $route.params
. Например:
Шаблон | Совпадающий путь | $route.params |
---|---|---|
/user/:username | /user/evan | { username: 'evan' } |
/user/:username/post/:post_id | /user/evan/post/123 | { username: 'evan', post_id: '123' } |
Кроме $route.params
, объект $route
предоставляют и другую полезную информацию, например $route.query
(если URL содержит строку запроса), $route.hash
, и т.д. Подробнее в справочнике API.
# Отслеживание изменений параметров
Важно отметить, что при переходе от /user/foo
к /user/bar
будет повторно использован тот же самый экземпляр компонента. Поскольку оба маршрута указывают на один и тот же компонент, этот подход эффективнее, чем уничтожение и повторное создание экземпляра. Но это означает, что хуки жизненного цикла компонента при этом вызываться не будут.
Чтобы реагировать на изменения параметров маршрута в рамках одного компонента, достаточно просто отслеживать изменения в объекте $route
:
const User = {
template: '...',
watch: {
$route(to, from) {
// обрабатываем изменение параметров маршрута...
}
}
}
Или можно воспользоваться хуком beforeRouteUpdate
, добавленным в версии 2.2:
const User = {
template: '...',
beforeRouteUpdate(to, from, next) {
// обрабатываем изменение параметров маршрута...
// не забываем вызвать next()
}
}
# Страница ошибки 404 / отслеживание ненайденных путей
Обычные параметры соответствуют символам между фрагментами URL, разделёнными /
. При необходимости чтобы совпадало что угодно можно воспользоваться звёздочкой (*
):
{
// сопоставляется со всем
path: '*'
}
{
// сопоставляется со всем, начинающимся с `/user-`
path: '/user-*'
}
Если используете маршруты со звёздочкой, убедитесь в их правильном порядке, чтобы они были в конце.
Маршрут { path: '*' }
обычно используют для страницы ошибки 404 на стороне клиента. При использовании Режима HTML5 History также проверьте что правильно сконфигурировали сервер.
При наличии звёздочки в $route.params
автоматически добавляется свойство pathMatch
. Оно будет содержать оставшуюся часть URL-адреса, сопоставленную со звёздочкой:
// Существует маршрут { path: '/user-*' }
this.$router.push('/user-admin')
this.$route.params.pathMatch // 'admin'
// Существует маршрут { path: '*' }
this.$router.push('/non-existing')
this.$route.params.pathMatch // '/non-existing'
# Продвинутые возможности сопоставления
vue-router
использует path-to-regexp (opens new window) в качестве движка для проверки совпадения маршрутов, что позволяет задействовать многие продвинутые возможности, включая опциональные динамические сегменты и регулярные выражения. Подробнее об этих продвинутых возможностях можно изучить в документации библиотеки (opens new window), а на примере (opens new window) узнать как использовать их совместно с vue-router
.
# Приоритеты при сопоставлении маршрутов
Иногда один и тот же URL может совпасть с несколькими маршрутами. В таких случаях приоритет определяется порядком определения маршрутов: чем раньше определён маршрут, тем выше у него приоритет.