1. 获取路由参数,将路由添加到路由集合中去
// 获取 路由信息
axios.post("/api/mock/getMenu")
     .then((resp) => {
        let datas = resp.data;
        // 遍历获取到的路由数组将其添加到全局路由中
        datas.forEach(v => {
        	v.component = routerCom(v.component);  // 处理下路径获取
            this.$router.addRoute("home", v); // 添加到name为home的路由的 子路由里面
            })
      })
      .catch(err=>{
			throw new Error(err);
	  })
// 处理组件文件路径,最后面会讲为什么使用这种方法
function routerCom(path) {
    return (resolve) => require([`components/${path}`], resolve);
}

第一步做完了,确实添加到全局路由中去了,也可以访问,但是页面一刷新,添加的路由丢失,又无法跳转,我采用了路由守卫的方式,在路由跳转的时候先对将要跳转到的路由进行判断是否存在,如果不存在,就去向后端获取,这样刷新也不会丢失了,(这种方式不太好,路由访问就要请求一次,建议使用 vuex 结合 sessionStorage 获取到后将其存储起来比较好。有时间修改一下)
2. 设置路由守卫

import VueRouter from 'vue-router'
import Vue from "vue"
Vue.use(VueRouter);
import axios from 'axios'
import routes from "../router-config/index"
// 将路由的push方法重写,解决连续跳转相同路由,出现报错的现象
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
    return originalPush.call(this, location).catch(err => err)
}
const router = new VueRouter({
    mode: "history",
    routes,
});
router.beforeEach((to, from, next) => {
    if (!to.matched.length) { // 当路由不存在的时候
        axios
            .post("/api/mock/getMenu")
            .then((resp) => {
                let datas = resp.data;
                datas.forEach(v => {
                    v.component = routerCom(v.component);
                    router.addRoute("home", v);
                })
            })
            .then(() => {
                next({
                    path: to.fullPath,
                });
            });
    }
    next();
})
function routerCom(path) {
    return (resolve) => require([`components/${path}`], resolve);
}
export default router;

记录一下遇到的坑
  • 通过 router.addRouter() 添加到全局的路由,不会在this.$router.options 中查询到,作者规定这样的,他说

    • options是传递给vuerouter构造函数的对象。 此后不会修改。

    • 可以通过router.getRouter() 去检测是否将获取的路由添加成功
  • component 路径赋值问题

    • 一开始 直接将路径获取函数写在了库里, 获取到的是字符串,在使用 eval() 转成js代码执行,结果会报 require is not defined,我又将 字符串 写成 import 获取的方式,结果又报 Failed to resolve module specifier 'components/page/dycRoute'。每当路由跳转的时候,就会报错,应该是,在路由跳转的环境里面不支持 require 、 import的形式。搜了什么资料,发现大家是通过写一个函数,先处理获取路径再去赋值的形式。

    解决方案

     function routerCom(path) {
     	return (resolve) => require([path], resolve);
     	// return () => import(path);
     }
    
    • 结果又出问题了,当我 使用 () => import("components/page/dycRoute") 或者是(resolve) => require(["components/page/dycRoute"], resolve); 将路径写死的时候正常,当我换成参数,就又开始报错了,webpackEmptyContext (eval at ./src/store/modules sync recursive (0.js:10), <anonymous>:2:10)我又搜了资料,发现
    • 错误原因是webpack打包逻辑,webpack4中动态import不支持变量方式,查看路由返回的信息,只是返回一个方法。

    解决方案

    • 可以通过字符串模板来提供部分信息给webpack,例如import(@/${path}), 这样编译时会编译所有@/views下的模块,但运行时确定path的值才会加载,从而实现懒加载。
    • 如果写了@给webpack还是不能识别,那么可能你需要多些几级的路径,如import(@/views/${path})
        return (resolve) => require([`components/${path}`], resolve);
    	// return () => import(`components/${path}`);
    

参考大佬链接:

vue动态路由异步加载import组件,加载不到module的问题
https://blog.csdn.net/Cookysurongbin/article/details/99307933

为什么router.addRoutes()添加的路由在 this.$router.options 看不到?
https://segmentfault.com/q/1010000021000331

vue中使用动态添加路由(router.addRoutes)加载权限侧边栏的两种方式
https://blog.csdn.net/hyl999/article/details/97159350

Logo

前往低代码交流专区

更多推荐