Динамические пути

Очень часто нам требуется сопоставить маршруты с заданным шаблоном с одним и тем же компонентом. Например, у нас может быть компонент 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>'
}

Вы можете посмотреть этот пример вживую здесь.

Может быть несколько динамических сегментов в одном маршруте. Для каждого сегмента появится соответствующее свойство в $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 в качестве движка для проверки совпадения маршрутов, что позволяет задействовать многие продвинутые возможности, включая опциональные динамические сегменты и регулярные выражения. Подробнее об этих продвинутых возможностях можно изучить в документации библиотеки, а на примере узнать как использовать их совместно с vue-router.

Приоритеты при сопоставлении маршрутов

Иногда один и тот же URL может совпасть с несколькими маршрутами. В таких случаях приоритет определяется порядком определения маршрутов: чем раньше определён маршрут, тем выше у него приоритет.