Vue守衛零基礎介紹
1. 全局導航守衛
語法:
# 守衛參數
+ to: Route: 即將要進入的目標 路由對象
+ from: Route: 當前導航正要離開的路由
+ next: Function: 一定要調用該next方法,否則路由不向下執行,頁面空白。# 全局前置守衛,當一個導航觸發時,立刻觸發前置守衛,
router.beforeEach((to, from, next) => {
// …
next()
})//全局解析守衛,等到路由獨享守衛和組件內守衛都解析完畢後執行
router.beforeResolve((to, from, next) => {
// …
next()
})# 全局後置鉤子,全部守衛執行完畢後執行
// 此鉤子不會接受 next 函數也不會改變導航本身
router.afterEach((to, from) => {
// …
})
全局導航守衛執行順序:
news.js(這個文件是從 index.js 文件中抽取拆分出來的,最終要被引入到 insex.js 文件中):
import News from '@/views/News' import Detail from '@/views/Detail' import Login from '@/views/Login' const routes = [ { path: '/news', component: News, }, { path: '/news/:id', name: 'xw', component: Detail, }, { // 這是登錄頁 path: '/login', component: Login, } ] export default routes
index.js:
import Vue from 'vue' import VueRouter from 'vue-router' import news from './routes/news' // 以插件的方式添加 Vue.use(VueRouter) // 實例化路由對象及配置路由表 const routes = [...news] const router = new VueRouter({ // 路由模式 mode: 'history', // 路由規則表 routes }) // 全局守衛 每次切換頁面都會執行到 // 前置 router.beforeEach((to, from, next) => { console.log('全局 --- beforeEach') next() }) // 解析 router.beforeResolve((to, from, next) => { console.log('全局 --- beforeResolve') next() }) // 後置 router.afterEach((to, from) => { console.log('全局 --- afterEach') }) export default router
登錄頁(index.vue):
<template> <div> <button>登錄用戶</button> </div> </template> <script> export default { } </script> <style lang="scss" scoped></style>
現在我們有這樣一個需求,用戶隻有在登錄成功之後,才能訪問新聞頁面,該怎麼做呢?
index.js:
import Vue from 'vue' import VueRouter from 'vue-router' import news from './routes/news' // 以插件的方式添加 Vue.use(VueRouter) // 實例化路由對象及配置路由表 const routes = [...news] const router = new VueRouter({ // 路由模式 mode: 'history', // 路由規則表 routes }) // 用全局前置守衛判斷用戶是否登錄 router.beforeEach((to, from, next) => { // 在使用導航守衛來驗證用戶是否登錄,一定要把登錄頁面路由排除掉,防止死循環 // 如果沒有在本地存儲中獲取到token值,並且即將跳轉的頁面不是登錄頁 if (!sessionStorage.getItem('token') && to.path != '/login') { // 到登錄頁面 // next('/login') // replace: true表示跳轉到登錄頁面後,不允許回退 next({ path: '/login', replace: true }) } else { next() } }) export default router
2. 路由獨享守衛
語法:
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... next() } } ] })
使用:
news.js(這個文件是從 index.js 文件中抽取拆分出來的,最終要被引入到 insex.js 文件中):
import News from '@/views/News' import Detail from '@/views/Detail' import Login from '@/views/Login' const routes = [ { path: '/news', component: News, }, { path: '/news/:id', name: 'xw', component: Detail, }, { // 這是登錄頁 path: '/login', component: Login, // 路由獨享守衛 // 隻有當前的路由規則才生效,比如登錄頁面的路由獨享守衛在進入新聞頁面時就不會生效 // 路由獨享守衛在每次進入到當前路由頁面時都會執行 beforeEnter: (to, from, next) => { console.log('路由獨享守衛 ==login -- --- beforeEnter') next() } } ] export default routes
3. 組件內守衛
語法:
你可以在路由組件內直接定義以下路由導航守衛:
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` } }
所有守衛和生命周期函數的執行順序:
news.js(這個文件是從 index.js 文件中抽取拆分出來的,最終要被引入到 insex.js 文件中):
import News from '@/views/News' import Detail from '@/views/Detail' import Login from '@/views/Login' const routes = [ { path: '/news', component: News, }, { path: '/news/:id', name: 'xw', component: Detail, beforeEnter: (to, from, next) => { console.log('路由獨享守衛 -- detail --- beforeEnter') next() } }, { // 這是登錄頁 path: '/login', component: Login, // 路由獨享守衛 // 隻有當前的路由規則才生效,比如登錄頁面的路由獨享守衛在進入新聞頁面時就不會生效 // 路由獨享守衛在每次進入到當前路由頁面時都會執行 beforeEnter: (to, from, next) => { console.log('路由獨享守衛 ==login -- --- beforeEnter') next() }, } ] export default routes
詳情頁(index.vue):
<template> <div> <h3>新聞詳情頁</h3> </div> </template> <script> export default { // 當路由訪問到此組件時,執行此鉤子函數 beforeRouteEnter(to, from, next) { console.log("組件 --- beforeRouteEnter"); next(); }, // 離開當前路由組件 beforeRouteLeave(to, from, next) { console.log("組件 --- beforeRouteLeave"); next(); }, // 路由參數的改變,觸發路由組件守衛 beforeRouteUpdate(to, from, next) { console.log(this); console.log("組件 --- beforeRouteUpdate"); next(); }, // 和生命周期函數比較以下執行順序 // 所有路由解析完畢以後,才開始執行生命周期函數 beforeCreate() { console.log('組件 === beforeCreate') }, beforeDestroy() { console.log('組件 === beforeDestroy') }, destroyed() { console.log('組件 === destroyed') }, }; </script> <style lang="scss" scoped></style>
下面我們來看beforeRouteUpdate
函數什麼時候執行。
詳情頁(index.vue):
<template> <div> <h3>新聞詳情頁</h3> <router-link to="/news/1">111</router-link><br /> <router-link to="/news/2">222</router-link><br /> <router-link to="/news/3">333</router-link> </div> </template> <script> export default { // 當路由訪問到此組件時,執行此鉤子函數 beforeRouteEnter(to, from, next) { console.log("組件 --- beforeRouteEnter"); next(); }, // 離開當前路由組件 beforeRouteLeave(to, from, next) { console.log("組件 --- beforeRouteLeave"); next(); }; // 路由參數的改變,觸發路由組件守衛 // 可以用來監聽頁面是否發生變化 beforeRouteUpdate(to, from, next) { // console.log(this); console.log("組件 --- beforeRouteUpdate"); next(); }, // 監聽器也可以用來監聽頁面是否發生變化 // watch:{ // '$route'(n){ // console.log('watch --- ' ,n); // } // }, // 和生命周期函數比較以下執行順序 // 所有路由解析完畢以後,才開始執行生命周期函數 beforeCreate() { console.log('組件 === beforeCreate') }, beforeDestroy() { console.log('組件 === beforeDestroy') }, destroyed() { console.log('組件 === destroyed') }, }; </script> <style lang="scss" scoped></style>
到此這篇關於Vue守衛零基礎介紹的文章就介紹到這瞭,更多相關Vue守衛內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Vue中路由守衛的具體使用
- vue-router鉤子函數實現路由守衛
- Vue路由router詳解
- vue中vue-router的使用說明(包括在ssr中的使用)
- vue-route路由管理的安裝與配置方法