Vue Navigation Guard (жизненный цикл маршрутизатора)

Vue.js

"навигация"Указывает, что маршрут меняется

vue-routerПредусмотренные навигационные охранники в основном используются для защиты навигации путем прыжка или отмены. Существует множество возможностей внедрения в процесс навигации по маршруту, и они делятся на три категории:

  • Глобальный
    • router.beforeEach
    • router.beforeResolve
    • router.afterEach
  • Эксклюзивно для одного маршрута
    • beforeEnter
  • компонентный уровень
    • beforeRouteEnter
    • beforeRouteUpdate
    • beforeRouteLeave

Примечание. Изменения параметров или запросов не вызывают охрану входа/выхода.(Вы можете наблюдать$routeобъект, чтобы реагировать на эти изменения, или использоватьbeforeRouteUpdateЗащита внутри компонента. )

Взглянем на картинку интуитивно:

Глобальная передняя защита

можно использоватьrouter.beforeEachЗарегистрируйте глобальную переднюю защиту

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

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

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

параметр

Каждый сторожевой метод получает три параметра:

  • to:Route: объект целевого маршрута, который собирается войти
  • from:Route: Маршрут, по которому уходит текущая навигация.
  • next:Function: Обязательно вызовите этот метод, чтобыresolveэтот крючок. Зависит от эффекта исполненияnextпараметры вызова метода
    • next()Перейдите к следующему крючку в конвейере. Если все хуки выполнены, состояние навигации подтверждается.
    • next(false): Прерывает текущую навигацию. Если URL-адрес браузера изменен (либо вручную пользователем, либо с помощью кнопки «Назад» в браузере), URL-адрес будет сброшен наfromАдрес, соответствующий маршруту.
    • next('/')илиnext({ path: '/' }): Перейти к другому адресу. Текущая навигация прерывается и создается новая. Вы можете спроситьnextПередайте произвольный объект положения и разрешите такие настройки, какreplace: true,name: 'home'варианты, такие какrouter-linkизto propилиrouter.pushварианты в .
    • next(error): (2.4.0+) если переданоnextявляется экземпляром Error, навигация завершается, и ошибка передается вrouter.onError()Зарегистрированный обратный звонок.

обязательно позвонитеnextметод, иначе хук не будет разрешен

глобальная защита синтаксического анализа

Можно использоватьrouter.beforeResolveЗарегистрируйте глобальную защиту. с участиемrouter.beforeEachАналогично, разница в том, что до подтверждения навигации,После того, как оба компонента защиты и асинхронного маршрута разрешены во всех компонентах, вызывается защита синтаксического анализа.

глобальный почтовый хук

Можно прописать глобальный почтовый хук, однако, в отличие от сторожей, эти хуки не будут приниматьnextФункция также не меняет саму навигацию.

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

Эксклюзивный охранник маршрута

Может быть определен непосредственно в конфигурации маршрутизацииbeforeEnterсторожить:

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

Эти средства защиты имеют те же параметры метода, что и глобальные предшествующие средства защиты.

Ограждения внутри компонентов

Конечно, следующие средства навигации по маршруту также могут быть определены непосредственно в компоненте маршрутизации:

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave
const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
	// 也就是进入新的组件时
    // 不能获取组件实例 `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` 访问组件实例
  })
}

УведомлениеbeforeRouteEnterзаключается в поддержкеnextЕдинственный охранник, который передает обратный вызов. дляbeforeRouteUpdateа такжеbeforeRouteLeaveСказать,thisуже доступен, так чтоне поддерживаетсяПередайте обратный вызов, так как он больше не нужен.

beforeRouteUpdate (to, from, next) {
  // just use `this`
  this.name = to.params.name
  next()
}

beforeRouteUpdateвызывается при изменении пути

Эта защита выхода обычно используется для предотвращения внезапного ухода пользователей без сохранения изменений. Эта навигация может быть выполнена черезnext(false)отменить.

beforeRouteLeave (to, from , next) {
  const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
  if (answer) {
    next()
  } else {
    next(false)
  }
}

Полный процесс анализа навигации

1. Навигация срабатывает
2. Вызвать охрану выхода в деактивированном компоненте.
3. Вызов глобальногоbeforeEachсторожить.
4. Вызовите его в повторно используемом компонентеbeforeRouteUpdateСтраж (2.2+).
5. Звоните в конфигурацию маршрутизацииbeforeEnter.
6. Разберите компоненты асинхронной маршрутизации.
7. Вызывается в активированном компонентеbeforeRouteEnter.
8. Вызов глобальногоbeforeResolveСтраж (2.5+).
9. Навигация подтверждена.
10. Вызов глобальногоafterEachкрюк.
11. ТриггерDOMвозобновить.
12. Звонок с созданным экземпляромbeforeRouteEnterпройти к охранникуnextфункция обратного вызова.

пример кода

//Router定义

Vue.use(Router)

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

//导航守卫

router.beforeEach((to, from, next) => {
  console.log("导航前置守卫: beforeEach,");
  next();
})
router.afterEach((to, from) => {
  console.log("导航后置守卫: afterEach,");
}) 
router.beforeResolve ((to, from, next) => {
  console.log("导航解析守卫: beforeResolve,");
  next();
})

Крюк компонента:

export default {
  //钩子
  beforeCreate(){
    console.log("组件钩子: beforeCreate");
  },
  created(){
    console.log("组件钩子: created");
  },
  beforeMount(){
    console.log("组件钩子: beforeMount");
  },
  mounted(){
    console.log("组件钩子: mounted");
  },
  beforeUpdate(){
    console.log("组件钩子: beforeUpdate");
  },
  updated(){
    console.log("组件钩子: updated");
  },
  beforeDestroy(){
    console.log("组件钩子: beforeDestroy");
  },
  destoryed(){
    console.log("组件钩子: destoryed");
  },
  beforeRouteEnter (to, from, next) {
    console.log("组件内部守卫: beforeRouteEnter,");
    next()
  },
  beforeRouteUpdate (to, from, next) {
    console.log("组件内部守卫: beforeRouteUpdate,");
    next()
  },
  beforeRouteLeave (to, from, next) {
    console.log("组件内部守卫: beforeRouteLeave,");
    next()
  }
}

Порядок вывода исполнения:

    导航前置守卫: beforeEach
    组件内部守卫: beforeRouteEnter
    导航解析守卫: beforeResolve
    导航后置守卫: afterEach
    组件钩子: beforeCreate
    组件钩子: created
    组件钩子: beforeMount
    组件钩子: mounted
    //执行跳转
    组件内部守卫: beforeRouteLeave
    导航前置守卫: beforeEach
    导航解析守卫: beforeResolve
    导航后置守卫: afterEach
    组件钩子: beforeDestroy

Чтобы узнать о жизненном цикле и функциях ловушек компонентов Vue, обратитесь к моей статье «Жизненный цикл Vue и функции ловушек».


^_<