思路:用户登录成功后获取token根据token去获取用户信息和路由信息,由于每次用户刷新界面动态存储在vuex的路由就会消失,所以我们要在路由拦截那一块处理一下;
1:通过路由钩子函数beforeEach中去判断如果用户数据丢失(及用户名不显示)去掉用户信息接口和路由接口;
await store.dispatch('user/getInfo');
具体代码;
// 获取异步用户信息
getInfo({ commit }) {
return new Promise((resolve, reject) => {
getApi().then(response => {
const { resp } = response;
commit('SET_NAME', resp.username);
resolve(resp);
}).catch(error => {
reject(error);
});
});
},
2:拿到用户信息和token这些,就可以去拿路由数据了
const asyncRoutes = await store.dispatch('GenerateRoutes');
具体代码
GenerateRoutes({ commit }) {
return new Promise(resolve => {
向后端请求路由数据
getRouters().then(res => {
const accessedRoutes = filterAsyncRouter(res.data);
console.log(accessedRoutes);
accessedRoutes.push({ path: '*', redirect: '/404', hidden: true });
commit('SET_ROUTES', accessedRoutes);
resolve(accessedRoutes);
});
});
}
2-1 filterAsyncRouter处理后台返回json路由转为前端能使用的路由 具体代码如下
// 遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap) {
return asyncRouterMap.filter(route => {
if (route.component) {
// Layout组件特殊处理
if (route.component === 'Layout') {
route.component = Layout;
} else {
route.component = loadView(route.component);
}
}
if (route.children != null && route.children && route.children.length) {
route.children = filterAsyncRouter(route.children);
}
return true;
});
}
3:拿到步骤2返回的路由信息添加到到自己的路由中
router.addRoutes(asyncRoutes);
4:刷新重载路由
next({ ...to, replace: true });
完整permmison.js代码如下
import router from './router';
import store from './store';
import { Message } from 'element-ui';
import { getToken } from '@/utils/auth';
import getPageTitle from '@/utils/get-page-title';
const whiteList = ['/login', '/forget'];
router.beforeEach(async(to, from, next) => {
document.title = getPageTitle(to.meta.title);
const hasToken = getToken();
if (hasToken) {
if (to.path === '/login') {
next({ path: '/' });
} else {
const hasGetUserInfo = store.getters.name;
if (hasGetUserInfo) {
// 路由跳转name不匹配的情况,通过path跳转不需判断
if (to.matched.length === 0) {
next('/404');
} else {
next();
}
} else {
try {
await store.dispatch('user/getInfo');
const asyncRoutes = await store.dispatch('GenerateRoutes');
router.addRoutes(asyncRoutes);
next({ ...to, replace: true });
} catch (error) {
await store.dispatch('user/resetToken');
Message.error(error || '获取用户信息失败');
next('/login');
}
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) {
next();
} else {
next(`/login`);
}
}
});
router.afterEach(() => {
});