"навигация"Указывает, что маршрут меняется
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) => {
// ...
}
}
]
})
Эти средства защиты имеют те же параметры метода, что и глобальные предшествующие средства защиты.
Ограждения внутри компонентов
Конечно, следующие средства навигации по маршруту также могут быть определены непосредственно в компоненте маршрутизации:
beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave
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 и функции ловушек».