由于目前的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拦截器配合使用。