完整的導航解析流程
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
的回調函數。
一 項目結構
二 main.js
import Vue from "vue"; import App from "./App.vue"; import router from "./router"; import store from "./store/index"; Vue.config.productionTip = false; new Vue({ router, store, render: h => h(App) }).$mount("#app");
三 App.vue
<template> <div id="app"> <h3>App組件</h3> <hr/> <router-view /> </div> </template> <script> export default {}; </script> <style lang="scss"> .link { margin-right: 10px; } </style>
四 router.js
import Vue from "vue";
import Router from "vue-router";
import Home from "./views/Home.vue";
import User from "./components/User.vue";
Vue.use(Router);
const router = new Router({
mode: "hash",
base: process.env.BASE_URL,
routes: [
{
path: "/",
name: "home",
component: Home,
beforeEnter(to, from, next) {
console.log("首頁路由獨享的守衛:beforeEnter");
next();
}
},
{
path: "/user/:id",
name: "user",
component: User,
props: true,
beforeEnter(to, from, next) {
console.log("用戶路由獨享的守衛:beforeEnter");
next(vm => {
console.log("首頁路由獨享守衛回調函數");
});
}
}
]
});
router.beforeEach((to, from, next) => {
console.log("全局前置守衛");
next();
});
router.beforeResolve((to, from, next) => {
console.log("全局解析守衛");
next();
});
router.afterEach((to, from) => {
console.log("全局后置鈎子");
});
export default router;
五 Home.vue
<template> <div class="home"> <h3>首頁</h3> <router-link to="/user/tom" class="link">湯姆</router-link> <router-link to="/user/jack" class="link">傑克</router-link> </div> </template> <script> export default { name: "home", beforeRouteEnter(to, from, next) { console.log("首頁組件內的守衛:beforeRouteEnter"); next(vm => { console.log("首頁組件內的守衛:beforeRouteEnter:回調函數"); }); }, beforeRouteUpdate(to, from, next) { console.log("首頁組件內的守衛:beforeRouteUpdate"); next(); }, beforeRouteLeave(to, from, next) { console.log("首頁組件內的守衛:beforeRouteLeave"); const answer = window.confirm( "Do you really want to leave? you have unsaved changes!" ); if (answer) { next(); } else { next(false); } } }; </script>
六 User.vue
<template> <div> <h4>{{id}}</h4> <button @click="$router.back()" class="link">首頁</button> <router-link to="/user/tom" class="link">湯姆</router-link> <router-link to="/user/jack" class="link">傑克</router-link> </div> </template> <script> export default { name: "user", props: ["id"], beforeRouteEnter(to, from, next) { console.log("用戶組件內的守衛:beforeRouteEnter"); next(vm => { console.log("用戶組件內的守衛:beforeRouteEnter:回調函數"); }); }, beforeRouteUpdate(to, from, next) { console.log("用戶組件內的守衛:beforeRouteUpdate"); next(); }, beforeRouteLeave(to, from, next) { console.log("用戶組件內的守衛:beforeRouteUpdate"); const answer = window.confirm( "Do you really want to leave? you have unsaved changes!" ); if (answer) { next(); } else { next(false); } } }; </script>
七 運行效果
進入首頁
從首頁進入用戶頁面(tom)
從用戶頁面(tom)進入用戶頁面(jack)