Сторожевые хуки

Как следует из названия, сторожевые хуки Vue-router используются для редиректов или отмены навигационных переходов. Есть несколько способов внедрить сторожевой хук: глобально, для конкретного пути, или для конкретного компонента.

Запомните изменение параметров не вызывает сторожевые хуки. Просто добавьте watch на объект $route для отслеживания этих изменений.

Глобальные хуки

Глобальный хук можно зарегистрировать через router.beforeEach:

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})

Глобальные сторожевые хуки вызываются в порядке создания при каждом навигационном переходе. Допускается асинхронное разрешение хуков — в этом случае переход считается незавершённым до тех пор, пока не будут разрешены все хуки.

В каждый сторожевой хук передаётся три параметра:

  • to: Route: целевой объект Route, к которому осуществляется переход.

  • from: Route: текущий путь, с которого осуществляется переход к новому.

  • next: Function: функция, вызов которой разрешает хук. В зависимости от переданных в next аргументов, результатом будет:

    • next(): переход к следующему хуку в цепочке. Если хуков больше нет, переход считается подтверждённым.

    • next(false): отмена перехода. Если URL был изменён (вручную пользователем, или кнопкой "назад"), он будет сброшен на соответствующий пути from.

    • next('/') или next({ path: '/' }): редирект на другой путь. Текущий переход будет отменён, и процесс начнётся заново для нового пути.

Удостоверьтесь, что функция next так или иначе будет вызвана, иначе хук никогда не будет разрешён.

Можно также зарегистрировать глобальные хуки, вызываемые после завершения перехода. Однако, в отличие от сторожевых хуков, в них не передаётся функция next, и на ход перехода они повлиять не могут:

router.afterEach((to, from) => {
  // ...
})

Указание хука для конкретного пути

Сторожевые хуки beforeEnter можно указать напрямую для конкретного пути в его конфигурации:

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

Эти хуки ничем не отличаются от глобальных.

Указание хука для конкретного компонента

Наконец, сторожевой хук можно указать и непосредственно в компоненте (том, что указан в конфигурации пути), используя следующие опции:

  • beforeRouteEnter
  • beforeRouteUpdate (добавлено в версии 2.2)
  • beforeRouteLeave
const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // вызывается до подтверждения пути, соответствующего этому компоненту.
    // НЕ имеет доступа к контексту инстанса компонента `this`,
    // так как к моменту вызова инстанс ещё не создан!
  },
  beforeRouteUpdate (to, from, next) {
    // вызывается когда маршрут, что рендерит этот компонент изменился,
    // но этот компонент будет повторно использован в новом маршруте.
    // Например, для маршрута с динамическими параметрами /foo/:id, когда мы
    // перемещаемся между /foo/1 и /foo/2, экземпляр того же компонента Foo
    // будет использован повторно, и этот хук будет вызван когда это случится.
    // Также имеется доступ в `this` к экземпляру компонента.
  },
  beforeRouteLeave (to, from, next) {
    // вызывается перед переходом от пути, соответствующего текущему компоненту;
    // имеет доступ к контексту инстанса компонента `this`.
  }
}

Хук beforeRouteEnter НЕ имеет доступа к this, так как к моменту его вызова навигация ещё не подтверждена, а значит и инстанс компонента ещё не создан.

Тем не менее, доступ к инстансу можно получить, передав коллбэк в next. Эта функция будет вызвана после подтверждения навигации, а экземпляр компонента будет передан в неё в качестве параметра:

beforeRouteEnter (to, from, next) {
  next(vm => {
    // инстанс компонента доступен как `vm`
  })
}

Внутри beforeRouteLeave можно обращаться к this напрямую. Этот сторожевой хук обычно используется для предотвращения случайного ухода пользователя с пути, содержащего несохранённые отредактированные данные. Переход можно отменить, вызвав next(false).

results matching ""

    No results matching ""