vue动态路由(后端传值)
思路:
总的来说就是从后端拿到路由数据,动态添加到路由表中。
问题:
如果有登录得先配置静态路由
细节:
1. 在路由中配置静态路由:
//定义静态路由
const staticRoutes = [
{
path: '/login',
name: 'Login',
component: () => import(/* webpackChunkName: "Login" */ '../views/Login'),
},
];
2. 在路由中设置路由守卫
//定义全局守卫
router.beforeEach(async (to, from, next) => {
//获取登录状态
const token = localStorage.getItem('token');
if (!token && to.name !== 'Login') {
return next('/login');
} else if (!token && to.name === 'Login') {
if (!token) next();
} else {
if (!store.state.hasGetRoute) {
// 如果没有获取路由信息,先从vuex获取路由信息而后跳转
store.dispatch('getRouteList').then(() => {
router.addRoutes(store.state.routeList);
// 如果直接使用 next() 刷新后会一直白屏
next({ ...to, replace: true });
});
} else {
// 如果已经获取路由信息,直接跳转
next();
}
}
});
3.vuex的中一些配置
const store = new Vuex.Store({
state: {
routeList: [],
hasGetRoute: false,
},
mutations: {
setRouteList(state, data) {
// 用路由解析函数解析 List 为真正的路由列表
state.routeList = filterAsyncRouter(data);
// 修改路由获取状态
state.hasGetRoute = true;
},
},
actions: {
getRouteList({ commit }) {
return new Promise(resolve => {
//axios获取路由结构
MetroApi({
url: '/user/get-user',
}).then(res1 => {
MetroApi({
url: '/role/menu-list',
params: {
roleId: res1.data.roleId,
},
}).then(res => {
let data = res.data;
//循环遍历出route结构,并添加动态路由
let navList = data.map(item => {
return {
name: item.menuName,
path: item.frontPath,
};
});
localStorage.setItem('navList', JSON.stringify(navList));
let routes = [
{
path: '/',
name: 'Index',
component: () => import('@/components/Layout'),
redirect: 'Workbench',
children: [...data],
},
];
// 注意这里取出的是 JSON 格式的路由列表
commit('setRouteList', routes);
resolve();
});
});
});
},
},
});
4.vuex中一些额外的方法
const loadView = viewPath => {
// 用字符串模板实现动态 import 从而实现路由懒加载
return () => import(`@/views${viewPath}`);
};
const filterAsyncRouter = routeList => {
return routeList.filter(route => {
if (route.frontPathComponent) {
// 利用懒加载函数将实际页面赋值给它
route.component = loadView(route.frontPathComponent);
route.name = route.menuName;
route.path = route.frontPathComponent || '/';
if (route.menuType === 'M' && route.children.length > 0) {
route.redirect = route.children[0].frontPathComponent;
}
}
// 判断是否存在子路由,并递归调用自己,如果不是路由就去掉(C、M这个是后台传来的层级)
if (route.menuType === 'C') {
route.children = [];
}
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children);
}
return true;
});
};
版权声明:本文为sinat_29498969原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。