vue将后端获取到的路由,通过 addRouter 动态添加。
获取路由参数,将路由添加到路由集合中去// 获取 路由信息axios.post("/api/mock/getMenu").then((resp) => {let datas = resp.data;// 遍历获取到的路由数组将其添加到全局路由中datas.forEach(v => {v.component = routerCom(v.component);// 处理下路径获取.
- 获取路由参数,将路由添加到路由集合中去
// 获取 路由信息
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}`);
- 一开始 直接将路径获取函数写在了库里, 获取到的是字符串,在使用 eval() 转成js代码执行,结果会报
参考大佬链接:
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
更多推荐
所有评论(0)