File: dynamic-matching.md

package info (click to toggle)
vue-router.js 3.4.9%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 3,212 kB
  • sloc: javascript: 7,982; sh: 22; makefile: 5
file content (104 lines) | stat: -rw-r--r-- 7,084 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# Динамические пути

Очень часто нам требуется сопоставить маршруты с заданным шаблоном с одним и тем же компонентом. Например, у нас может быть компонент `User`, который должен отображаться для всех пользователей, но с разными ID пользователей. Во `vue-router` мы можем использовать динамический сегмент в маршруте, чтобы достичь этого:

```js
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`:

```js
const User = {
  template: '<div>Пользователь {{ $route.params.id }}</div>'
}
```

Вы можете посмотреть этот пример вживую [здесь](https://jsfiddle.net/yyx990803/4xfa2f19/).

Может быть несколько динамических сегментов в одном маршруте. Для каждого сегмента появится соответствующее свойство в `$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](../../api/#объект-route).

## Отслеживание изменений параметров

Важно отметить, что при переходе от `/user/foo` к `/user/bar` **будет повторно использован тот же самый экземпляр компонента**. Поскольку оба маршрута указывают на один и тот же компонент, этот подход эффективнее, чем уничтожение и повторное создание экземпляра. **Но это означает, что хуки жизненного цикла компонента при этом вызываться не будут**.

Чтобы реагировать на изменения параметров маршрута в рамках одного компонента, достаточно просто отслеживать изменения в объекте `$route`:

```js
const User = {
  template: '...',
  watch: {
    $route(to, from) {
      // обрабатываем изменение параметров маршрута...
    }
  }
}
```

Или можно воспользоваться [хуком `beforeRouteUpdate`](../advanced/navigation-guards.md), добавленным в версии 2.2:

```js
const User = {
  template: '...',
  beforeRouteUpdate (to, from, next) {
    // обрабатываем изменение параметров маршрута...
    // не забываем вызвать next()
  }
}
```

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

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

```js
{
  // сопоставляется со всем
  path: '*'
}
{
  // сопоставляется со всем, начинающимся с `/user-`
  path: '/user-*'
}
```

Если используете маршруты со _звёздочкой_, убедитесь в их правильном порядке, чтобы они были в конце.
Маршрут `{ path: '*' }` обычно используют для страницы ошибки 404 на стороне клиента. При использовании _Режима HTML5 History_ также проверьте что [правильно сконфигурировали сервер](./history-mode.md).

При наличии _звёздочки_ в `$route.params` автоматически добавляется свойство `pathMatch`. Оно будет содержать оставшуюся часть URL-адреса, сопоставленную со _звёздочкой_:

```js
// Существует маршрут { 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](https://github.com/pillarjs/path-to-regexp/tree/v1.7.0) в качестве движка для проверки совпадения маршрутов, что позволяет задействовать многие продвинутые возможности, включая опциональные динамические сегменты и регулярные выражения. Подробнее об этих продвинутых возможностях можно изучить в [документации библиотеки](https://github.com/pillarjs/path-to-regexp/tree/v1.7.0#parameters), а на [примере](https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js) узнать как использовать их совместно с `vue-router`.

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

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