Appearance
47.Vue-Router 有几种钩子函数,具体是什么及执行流程是怎样的?
- 导航被触发。
- 在失活的组件里调用 beforeRouteLeave 守卫。
- 调用全局的 beforeEach 守卫。
- 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
- 在路由配置里调用 beforeEnter。
- 解析异步路由组件。
- 在被激活的组件里调用 beforeRouteEnter。
- 调用全局的 beforeResolve 守卫 (2.5+)。
- 导航被确认。
- 调用全局的 afterEach 钩子。
- 触发 DOM 更新。
- 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。
模拟守卫运行
js
// 1.实现sleep方法用于延迟
async function sleep(n = 1000) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, n);
});
}
// 2.模拟离开钩子
const routeLeaveGuards = [
() => {
console.log("leave1");
return sleep(3000);
},
() => {
console.log("leave2");
},
];
// 3.模拟进入钩子
const beforeEachGuards = [
(next) => {
console.log("each1");
setTimeout(() => {
next();
}, 10000);
},
() => {
console.log("each2");
},
];
// 4.当前要运行的钩子,将钩子转化成promise
let guards = [];
function guardToPromiseFn(guard) {
return () =>
new Promise((resolve, reject) => {
const next = resolve;
let guardReturn = guard(next);
Promise.resolve(guardReturn).then(next);
});
}
for (let guard of routeLeaveGuards) {
guards.push(guardToPromiseFn(guard));
}
// 5.组合钩子
function runGuardQueue(guards) {
return guards.reduce(
(promise, guard) => promise.then(() => guard()),
Promise.resolve()
);
}
runGuardQueue(guards).then(() => {
guards = [];
for (let guard of beforeEachGuards) {
guards.push(guardToPromiseFn(guard));
}
return runGuardQueue(guards);
});
// 1.实现sleep方法用于延迟
async function sleep(n = 1000) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, n);
});
}
// 2.模拟离开钩子
const routeLeaveGuards = [
() => {
console.log("leave1");
return sleep(3000);
},
() => {
console.log("leave2");
},
];
// 3.模拟进入钩子
const beforeEachGuards = [
(next) => {
console.log("each1");
setTimeout(() => {
next();
}, 10000);
},
() => {
console.log("each2");
},
];
// 4.当前要运行的钩子,将钩子转化成promise
let guards = [];
function guardToPromiseFn(guard) {
return () =>
new Promise((resolve, reject) => {
const next = resolve;
let guardReturn = guard(next);
Promise.resolve(guardReturn).then(next);
});
}
for (let guard of routeLeaveGuards) {
guards.push(guardToPromiseFn(guard));
}
// 5.组合钩子
function runGuardQueue(guards) {
return guards.reduce(
(promise, guard) => promise.then(() => guard()),
Promise.resolve()
);
}
runGuardQueue(guards).then(() => {
guards = [];
for (let guard of beforeEachGuards) {
guards.push(guardToPromiseFn(guard));
}
return runGuardQueue(guards);
});