全局前置路由守卫。beforeEach()在初始化和每一次路由切换之前调用函数,控制用户信息的获取
router.beforeEach((to, from, next) =>
{
if(store.state.token)
{
//路径如果是请求的login登录页面,但是又存在token,并且有账户信息
//证明用户登陆过,不能重复登录,则跳转到首页
if(to.path ==="/login" && store.state.account.length)
{
next({path: "/"});
}else //跳的是登录界面,但是没有账户信息
{
//判断是否有账号信息,如果没有,则获取
if(store.state.account.length === 0)
{
//需要获取用户信息
store.dispatch("getUserInfo").then((res)=>
{
next();
}).catch((err)=>
{
Message({
type:"warning",
showClose:true,
message:"登录已过期!"
});
next({path: "/login"})
})
}else
{
//如果有用户信息,直接放行
next();
}
}
}else
{
if (to.matched.some(r => r.meta.requireLogin))
{
Message({
type: 'warning',
showClose: true,
message: '请先登录哦'
})
} else
{
next();
}
}
});
store里面的getUserInfo:
getUserInfo({commit})
{
return new Promise((resolve, reject) =>
{
// 异步处理
// 处理结束后、调用resolve 或 reject
// 当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...)
getUserInfo().then((res) =>
{
if(res.data.success)
{
commit('SET_ID', res.data.data.id);
commit('SET_ACCOUNT', res.data.data.account);
commit('SET_NAME', res.data.data.name);
commit('SET_AVATAR', res.data.data.avatar);
resolve(res.data);
}else
{
commit('SET_ID', "");
commit('SET_ACCOUNT', "");
commit('SET_NAME',"");
commit('SET_AVATAR', "");
commit("SET_TOKEN","");
reject(res.data.msg);
}
}).catch((error) =>
{
commit('SET_ID', "");
commit('SET_ACCOUNT', "");
commit('SET_NAME',"");
commit('SET_AVATAR', "");
commit("SET_TOKEN","");
reject(error)
})
})
}
获取到用户信息后,登录按钮需要修改为用户的头像
BaseHeader:
<template v-if="!user.login">
<el-menu-item index="/login">
<el-button type="text">登录</el-button>
</el-menu-item>
<el-menu-item index="/register">
<el-button type="text">注册</el-button>
</el-menu-item>
</template>
<template v-else>
<el-submenu index>
<template slot="title">
<img class="my-header-picture" :src="user.avatar"/>
</template>
<el-menu-item index @click="logout"><i class="el-icon-back"></i>退出</el-menu-item>
</el-submenu>
</template>
<script>
export default {
computed: {
user()
{
let login = this.$store.state.account.length !== 0;
let avatar = this.$store.state.avatar;
return{
login,avatar
}
}
}
}
</script>
每次路由在初始化或者切换后都会调用前置路由守卫,
前置路由守卫会调用store里面的getUserInfo获取用户信息,存储在vuex里面,
然后BaseHeader会通过计算属性,自动计算user的值,如果获取了用户信息,会就把登录、注册按钮变为用户的头像 。
流程:
用户注册或者登录,获取token存到vuex和local Storage,跳转路由到首页=》全局前置路由守卫获取用户信息,存储在vuex=》baseHeader通过计算属性在vuex里面获取user的值,把登录、注册按钮变为用户的头像 。