Skip to content
Перевод синхронизирован с документацией от , хэш коммита 960662d.

Сопоставление динамических маршрутов с параметрами

Очень часто нам придется сопоставлять маршруты с заданным шаблоном с одним и тем же компонентом. Например, у нас может быть компонент User, который должен отображаться для всех пользователей, но с разными ID пользователей. Во Vue Router мы можем использовать динамический сегмент в маршруте, чтобы достичь этого, Этот сегмент называется параметром (param):

js
import User from './User.vue'

// маршруты передаются в `createRouter`.
const routes = [
  // динамические сегменты начинаются с двоеточия
  { path: '/users/:id', component: User },
]

Теперь URL-адреса типа /users/johnny и /users/jolyne будут сопоставляться с одним и тем же маршрутом.

Параметр обозначается двоеточием :. Когда маршрут найден, значение его параметров будет раскрываться как route.params в каждом компоненте. Таким образом, мы можем вывести ID текущего пользователя, обновив шаблон User на следующий:

vue
<template>
  <div>
    <!-- The current route is accessible as $route in the template -->
    User {{ $route.params.id }}
  </div>
</template>

В одном маршруте может быть несколько параметров, которые будут сопоставлены с соответствующими полями в route.params. Примеры:

шаблонсопоставленный путьroute.params
/users/:username/users/eduardo{ username: 'eduardo' }
/users/:username/posts/:postId/users/eduardo/posts/123{ username: 'eduardo', postId: '123' }

Помимо route.params, объект route также предоставляет другую полезную информацию, такую как route.query (если есть query в URL), route.hash и так далее. Вы можете ознакомиться с полными деталями в справочнике по API.

Рабочую демонстрацию этого примера можно найти здесь.

Реагирование на изменение параметров

Следует отметить, что при использовании маршрутов с параметрами, когда пользователь переходит с /users/johnny на /users/jolyne, будет использоваться тот же экземпляр компонента. Поскольку оба маршрута отображают один и тот же компонент, это более эффективно, чем уничтожение старого экземпляра и создание нового. Однако это также означает, что хуки жизненного цикла компонента не будут вызваны.

Для реагирования на изменения параметров в том же компоненте, вы можете просто следить за любым свойством объекта route, в данном случае за route.params:

vue
<script setup>
import { watch } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()

watch(
  () => route.params.id,
  (newId, oldId) => {
    // обработка изменения параметров маршрута...
  }
)
</script>
vue
<script>
export default {
  created() {
    this.$watch(
      () => this.$route.params.id,
      (newId, oldId) => {
        // обработка изменения параметров маршрута...
      }
    )
  },
}
</script>

Или воспользуйтесь хуком навигации beforeRouteUpdate, который также позволяет вам отменить навигацию:

vue
<script setup>
import { onBeforeRouteUpdate } from 'vue-router'
// ...

onBeforeRouteUpdate(async (to, from) => {
  // обработка изменения параметров маршрута...
  userData.value = await fetchUser(to.params.id)
})
</script>
vue
<script>
export default {
  async beforeRouteUpdate(to, from) {
    // обработка изменения параметров маршрута...
    this.userData = await fetchUser(to.params.id)
  },
  // ...
}
</script>

Страница ошибки 404 / отслеживание ненайденных маршрутов

Обычные параметры будут соответствовать только символам между фрагментами URL, разделенными символом /. Если вы хотите сопоставить любые символы, вы можете использовать пользовательское регулярное выражение для параметра, добавив его в скобках сразу после параметра:

js
const routes = [
  // будет сопоставляться всем маршрутам и будет помещено в `route.params.pathMatch`.
  { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
  // будет сопоставляться всему, что начинается с `/user-`, и будет помещено в `route.params.afterUser`.
  { path: '/user-:afterUser(.*)', component: UserGeneric },
]

В данном конкретном случае мы используем пользовательское регулярное выражение, заключенное в круглые скобки, и помечаем параметр pathMatch как опционально повторяемый. Это позволяет нам при необходимости перейти прямо к этому маршруту, разбив path на массив:

js
router.push({
  name: 'NotFound',
  // сохранить текущий путь и удалить первый символ, чтобы целевой URL не начинался с `//`.
  params: { pathMatch: route.path.substring(1).split('/') },
  // сохраняем существующий запрос и хэш, если таковой имеется
  query: route.query,
  hash: route.hash,
})

Подробнее см. в разделе повторяющиеся параметры.

Если вы используете History mode, обязательно следуйте инструкциям по правильной настройке вашего сервера.

Продвинутые возможности сопоставления

Vue Router использует свой собственный синтаксис сопоставления путей, вдохновленный синтаксисом, используемым в express, поэтому он поддерживает множество продвинутых шаблонов сопоставления, таких как опциональные динамические сегменты и регулярные выражения. Пожалуйста, ознакомьтесь с документацией по продвинутому сопоставлению, чтобы изучить их подробнее.

Released under the MIT License.