样式中也可以使用@符,切记在前面加上~
//其中assets是存放共用的文件
background: url(~@/assets/images/icons.png) no-repeat -10px -201px;
注册业务|登录业务
🌟登录
//actions
async userLogin({commit},data){
let result = await reqUserLogin(data);
// 服务器下发token,用户唯一标识符(uuid)
// 将来经常通过带token找服务器要用户信息进行展示
// console.log(result);
if(result.code == 200){
// 用户登录成功且获取到token
commit('USERLOGIN',result.data.token);
// 持久化存储token
setToken(result.data.token);
return 'ok';
}else{
return Promise.reject(new Error('faile'));
}
},
//utils
export const setToken = (token)=>{
localStorage.setItem('TOKEN',token);
}
export const getToken =()=>{
return localStorage.getItem('TOKEN');
}
// 清除本地token
export const removeToken = ()=>{
localStorage.removeItem('TOKEN');
}
🌟退出登录
// 退出登录 actions
async userLogout({commit}){
// 向服务器发送请求清空token
let result = await reqLogout();
if(result.code == 200){
// action不能操作state,提交mutation修改state
commit('CLEAR');
return 'ok';
}else{
return Promise.reject(new Error('faile'));
}
},
//mutaions
// 仓库中想关用户信息清空,本地存储的信息清空
CLEAR(state){
state.token = '';
state.userInfo = {};
removeToken();
}
//js
async logout(){
// 退出登录需要做的事:1.发请求通知服务器退出登录【清除一些数据:token】
// 2.清除项目当中的数据【userInfo、token】
try {
await this.$store.dispatch('userLogout');
// 退出登录后回到首页
this.$router.push('/home');
} catch (error) {
}
}
💁🏼♀️遇到的问题1:当用户注册完成,用户登录[用户名+密码]向服务器发请求,(组件派发请求'userlogin')登录成功获取token存储于仓库当中,(非持久化)路由跳转到home首页。 在首页当中mounted派发action(getuserInfo)获取用户信息,一级动态展示header组件内容。 一刷新home首页,获取不到用户信息,(token:vuex非持久化存储)
💁🏼♀️遇到的问题2:多个组件当中都要获取用户信息,需要在每个组件的mounted中触发this.$store.dispatch('getUserInfo')
💁🏼♀️遇到的问题3:用户已经登录了就不应该再回登录页。
💁🏼♀️遇到的问题4:用户可以输入URL进行路由跳转,这应该禁止。
解决方法:使用导航守卫
导航:表示路由正在发送改变,进行路由跳转 守卫:守护判断身份是否符合条件
全局守卫:只要发送路由的变化,守卫就能监听到
路由独享守卫:
组件内守卫:
登陆页面时如果有token则表示已登录:进入判断是否进入login页面,如果不是则全页放行,判断是否获取用户信息,如果没有获得则派发action进行捞数据,如果捞数据失败则说明token失效则重新登录并且跳转到登录页面;如果没有token则表示没有登录,进入游客状态
// 全局守卫:前置守卫(在路由跳转之前进行判断)
router.beforeEach(async (to,from,next)=>{
// to:可以获取到你要跳转到那个路由信息
// from:可以获取到你从那个路由得来的信息
// next:放行函数 next()放行
// next('/login')放行到指定的位置
// next(false):中断当前的导航,如果浏览器的URL改变了(可能是用户手动或者浏览器后退按钮)
// 那么URL地址会重置到from路由对应的地址
// next();//测试
// 引入store 判断用户是否登录过了(token是否有),未登录一定不会有token
console.log(store.state.user.token);
let token = store.state.user.token;
let name = store.state.user.userInfo.name;
if(token){
// 用户登录过了后不能再去login页面
if(to.path == '/login' || to.path == '/register'){
next('/home');
}else{
// 如果有用户信息就放行
if(name){
next();
}else{
try {
// 没有用户信息就重新派发action让仓库存储用户的信息再跳转
await store.dispatch('getUserInfo');
next();
} catch (error) {
// token失效了获取不到用户数据了
// 清空token
store.dispatch('userLogout');
// 跳到登陆页
next('/login');
}
}
}
}else{
// 没有登录的话不能去交易相关的,不能去支付相关的,不能去个人中心
//记录要去的地址
let topath = to.path;
if(topath.indexOf('/trade')!=-1 || topath.indexOf('/pay')!=-1 || topath.indexOf('/shopcart')!=-1){
// 优化:用户没有登录时想去的地方保存下来后登录后再进行跳转
//利用query获取路由信息
next('/login?redirect='+topath);
}else{
// 去的不是则放行
next();
}
next();
}
});
🌟退出登录
//此时的登录页面会根据用户点击过的topath去执行登录结束后的跳转。
async userLogin(){
try {
// 登录成功
const {phone,password} = this;
(phone&&password)&& await this.$store.dispatch('userLogin',{phone,password});
//如果query有值就把路由信息赋给topath,没有则跳转至/home
let topath = this.$route.query.redirect||'/home';
// 跳转
this.$router.push(topath);
} catch (error) {
alert(error.mess);
}
}
}
🌟独享路由守卫
{
//在单独的路由上实现
path:'/trade',
name:'trade',
component:Trade,
meta:{show:true},
beforeEnter:(to,from,next)=>{
if(from.path == '/shopcart'){
next();
}else{
//阻断当前的路由导航跳转
next(false);
}
}
},