由於目前的Vue移動端項目最后會被封裝為安卓應用,所以需要一個登錄攔截並保存登錄狀態。
這里演示的內容是將所需的狀態碼記錄到localStorage內(這里本地保存的狀態是“Flag”,如果需使用token的可以考慮將token保存道cookies或者localStroage內),代碼內涉及到的“Toast”為我工程內引入的muse-ui的Toast插件。
1、vue-router的改動(router/index.js):
在路由設置的每個頁面路徑下增加meta,通過這個字段來判斷該路由是否需要登錄權限,isLogin:false表示不需要驗證權限即可進入的頁面,isLogin:true是需要登錄權限驗證才能進入的頁面
1 routes: [ 2 { 3 path: '/', 4 name: 'WelcomePage', 5 component: WelcomePage, 6 meta: { 7 isLogin: false 8 } 9 }, 10 { 11 path: '/Login', 12 name: 'LoginPage', 13 component: LoginPage, 14 meta: { 15 isLogin: false 16 } 17 }, 18 { 19 path: '/Home', 20 name: 'HomePage', 21 component: HomePage, 22 meta: { 23 isLogin: true 24 } 25 }, 26 { 27 path: '/Message', 28 name: 'MessagePage', 29 component: MessagePage, 30 meta: { 31 isLogin: true 32 } 33 }, 34 { 35 path: '/User', 36 name: 'UserPage', 37 component: UserPage, 38 meta: { 39 isLogin: true 40 } 41 } 42 ]
2、main.js內的改動:
這里我將路由守衛寫到了main.js 內,這個根據個人安排也可以放到router的相關文件內,不過需要一些小改動。
利用vue-router提供的鈎子函數beforeEach對路由進行判斷:
1 router.beforeEach((to, from, next) => { 2 let getFlag = localStorage.getItem('Flag') /* 這里是判斷用戶是否登錄過,因為在用戶登錄后會在localStroage內存儲Flag=isLogin */ 3 if (getFlag === 'isLogin') { /* 如果存在Flag並且為isLogin意味着用戶登錄,這時修改vux內state下isLogin的狀態 */ 4 store.state.isLogin = true 5 next() 6 if (!to.meta.isLogin) { /* 如果在有登錄狀態的情況下前往不需要權限的路由路徑,則判定為退出登錄,進行提示並跳轉登錄頁 */ 7 Toast.info('退出成功') 8 next({ 9 path: '/Login' 10 }) 11 } 12 } else { 13 if (to.meta.isLogin) { /* 如果沒有登錄狀態且要去往需要權限的路徑時跳轉登錄頁並進行提示 */ 14 next({ 15 path: '/Login' 16 }) 17 Toast.info('請先登錄') 18 } else { 19 next() 20 } 21 } 22 }) 23 24 router.afterEach(route => { 25 window.scroll(0, 0) 26 })
鈎子函數beforeEach方法接收三個參數: to、from、next;
- to: Route: 即將要進入的目標路由對象
- from: Route: 當前導航正要離開的路由
- next: Function: 一定要調用該方法來 resolve 這個鈎子。執行效果依賴 next 方法的調用參數。
其中next需要注意的是:
- next(): 進行管道中的下一個鈎子。如果全部鈎子執行完了,則導航的狀態就是 confirmed (確認的)。
- next({ path: ‘/’ }): 跳轉到一個不同的地址。當前的導航被中斷,然后進行一個新的導航。
確保要調用 next 方法,否則鈎子就不會被 resolved。
“to.meta”中是我們自定義的數據,其中就包括我們剛剛定義的isLogin字段,通過這個字段來判斷該路由是否需要登錄權限。
3、Vuex的相關設置(vuex/index.js):
1 import Vue from 'vue' 2 import Vuex from 'vuex' 3 4 Vue.use(Vuex) 5 6 export default new Vuex.Store({ 7 state: { 8 isLogin: false 9 }, 10 getters: { 11 isLogin: state => state.isLogin 12 }, 13 mutations: { 14 userStatus (state, flag) { 15 state.isLogin = flag 16 } 17 }, 18 actions: { 19 setUser ({commit}, flag) { 20 commit('userStatus', flag) 21 } 22 } 23 })
4、登錄及退出登錄的需要注意的點:
注意標紅的內容。
登錄:
1 loginBack (res) { 2 let resBack = res.Back 3 let resData = res.Data 4 if (resBack === '1') { 5 this.loginLoading = false 6 let userName = this.userName 7 this.$store.dispatch('setUser', true) 8 localStorage.setItem('Flag', 'isLogin') 9 localStorage.setItem('username', userName) 10 this.$toast.info(resData) 11 this.$router.replace('/Home') 12 } else { 13 this.loginLoading = false 14 this.$toast.error(resData) 15 } 16 }
退出登錄:
1 loginOut () { 2 localStorage.removeItem('Flag') 3 localStorage.removeItem('username') 4 this.$toast.info('退出成功') 5 this.$router.replace('/Login') 6 }
這樣基本上能實現登錄權限攔截功能了,實際中如果需要帶上token驗證的,可以和axios攔截器配合使用。