Vue 动态路由 坑点

main.js代码

坑点动态路由里面的component

在后台配置的是

component: () => import("@" + component)

 会报错Error:cannot find module ‘@/’ 找不到

 组件的导入可以使用字符串拼接的方式导入,可以使用模板字符串导入(字符串中含有变量),但是使用模板字符串导入时不能够只使用变量!!必须指定一个目录,不能全用变量

代替!

还有一种情况报错

在使用若依或者elementui-admin等框架时

解决办法

component: (resolve) => require([`@/views/${module}/index`], resolve)

具体原因链接:

vue实现动态路由一步到位_vue动态路由怎么实现_ds_surk的博客-CSDN博客

Vue配置动态路由报错:Error: Cannot find module ‘@/views/login/index’

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);

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值