main.js代码
坑点动态路由里面的component
在后台配置的是
component: () => import("@" + component)
会报错Error:cannot find module ‘@/’ 找不到
组件的导入可以使用字符串拼接的方式导入,可以使用模板字符串导入(字符串中含有变量),但是使用模板字符串导入时不能够只使用变量!!必须指定一个目录,不能全用变量
代替!
还有一种情况报错
在使用若依或者elementui-admin等框架时
解决办法
component: (resolve) => require([`@/views/${module}/index`], resolve)
具体原因链接:
async function getMenu(data) {//获取菜单列表
function handleTree(data) {//平级结构转换树形结构
let map = {};//用于映射
data.forEach(item => {
const { route, component, name, meta, icon, isAdmin } = item;//根据自己路由的配置取参数
map[item.id] = {
path: route,
component: () => import("@/views" + component),
name,
meta: eval(`( ${meta} )`),//由于路由元信息配置的是字符串 eval字符串转对象
iconCls: icon,
isAdmin: isAdmin === "True" ? "1" : "0",
children: []
};
});
data.forEach(item => {
if (item.parent_id !== "-1") {
map[item.parent_id].children.push(map[item.id]);
} else {
router.options.routes.push(map[item.id]);
}
});
router.addRoutes(router.options.routes);
}
let res = await WebApi({
command: "I_Menu_Get",
data: {
code: "", //编码
name: "", //名称
is_menu: "", //是否菜单
page_index: 1, //当前页
page_size: 9999 //页容量
}
});
handleTree(res.data);
}
路由守卫 解决刷新白屏/404问题
刷新白屏
先确认自己在route.js 或者 main.js 中有没有使用 路由守卫vue.beforeEach和vue.addRouters() 促使页面每次刷新,重新根据后台返回数据生成动态路由
let hasRoles =true 用于每次刷新都能够 重新获取动态路由表
if (hasRoles) { hasRoles = false;//必须在getMenu() 执行 getMenu(); next({ ...to, replace: true }); }
next({ ...to, replace: true }); 必不可少的,确保你的动态路由创建成功再去执行其它代码
在hash模式下 你的动态路由可能还没创建完成就 跑其它代码了 毕竟 路由守卫是异步操作 在history模式下 可能没有这个问题 未实测 写上最好
let hasRoles = true;//通过hasRoles变量控制 避免陷入死循环
router.beforeEach(async (to, from, next) => {
let user = JSON.parse(sessionStorage.getItem("user"));
let bologin = JSON.parse(sessionStorage.getItem("bologin"));
let userPowerData = JSON.parse(sessionStorage.getItem("userPower"));
if (to.path == "/login") {
sessionStorage.removeItem("user");
sessionStorage.removeItem("bologin");
sessionStorage.removeItem("userPower");
}
//你的一系列权限判断代码
if (!bologin && to.path != "/login") {
next({
path: "/login"
});
} else if (to.meta.power_code || to.meta.adminPower) {
if (user.is_admin === "True") {
next();
} else {
if (
!userPowerData.some(val => val.code == to.meta.power_code) ||
to.meta.adminPower === "1"
) {
next(false);
} else {
next();
}
}
} else {
if (hasRoles) {
hasRoles = false;
getMenu();
next({ ...to, replace: true });
} else {
next();
}
}
});
刷新出现404
原因:由于创建路由时会创建login、404等其他页面。刷新的时候将不匹配地址同意导航到404页面了
let routes = [ { path: "/login", component: Login, name: "", hidden: true }, { path: "/404", component: NotFound, name: "", hidden: true }, { path: "*", redirect: { path: "/404" }, hidden: true }, ]
这就导致在动态权限添加路由的时候,所加的权限路由在使用地址匹配是都会被拦截到404页面。输入网址导航会,刷新页面会,在页面中通过点击等方式直接触发的路由不会出现404。
所以将此路由(404)从静态路由表去除,放到动态权限路由获取后再addRouter。
function getMenu(){ ...处理路由,等路由全都添加进去以后 //添加404 router.options.routes.push({//我是直接添加到router,如果用的vuex 原理一样 path: "*", redirect: { path: "/404" }, hidden: true }); //最后添加全部路由 router.addRoutes(router.options.routes); }
最后顺便写两个处理结构的方法
平级结构转树形结构
function buildTree(list) {
let map = {};
let tree = [];
// 将列表转换为映射表,方便快速查找
list.forEach(item => {
map[item.id] = { ...item, children: [] };
});
// 构建树形结构
list.forEach(item => {
if (item.parentId) {
map[item.parentId].children.push(map[item.id]);
} else {
tree.push(map[item.id]);
}
});
return tree;
}
// 示例数据
let list = [
{ id: 1, name: 'A', parentId: null },
{ id: 2, name: 'B', parentId: 1 },
{ id: 3, name: 'C', parentId: 1 },
{ id: 4, name: 'D', parentId: 2 },
{ id: 5, name: 'E', parentId: 2 },
{ id: 6, name: 'F', parentId: 3 },
];
let tree = buildTree(list);
console.log(tree);
树形结构转平级结构
function flattenTree(tree) {
let list = [];
function traverse(node, parentId = null) {
let item = { ...node, parentId };
list.push(item);
if (node.children && node.children.length > 0) {
node.children.forEach(child => {
traverse(child, node.id);
});
}
}
tree.forEach(node => {
traverse(node);
});
return list;
}
// 示例数据
let tree = [
{
id: 1,
name: 'A',
children: [
{
id: 2,
name: 'B',
children: [
{ id: 4, name: 'D', children: [] },
{ id: 5, name: 'E', children: [] }
]
},
{
id: 3,
name: 'C',
children: [
{ id: 6, name: 'F', children: [] }
]
}
]
}
];
let list = flattenTree(tree);
console.log(list);