vue当中addRoutes动态添加路由白屏解决和next(),next("/")的一些区别
问题产生前言
使用动态添加路由
router.addRoutes()
后进入一个页面,对着这一个页面刷新一下,然后页面就白屏了并且不管刷新多少次都没有用,依旧是白屏,只有重新进入页面才有效果- 比如对于网站
http://localhost:9528/#/product/attr/list
,现在显示是正常的,对着这一个页面刷新一下,页面就白屏了,刷新多少次都没有用,必须要重新访问一次路由才可以必须要重新访问一次网站才可以(只要不再次刷新就可以)
- 比如对于网站
问题分析
动态添加路由无非就是几个过程
- router.addRoutes();
- 页面访问动态生成的路由
步骤1没有问题,问题就出现在页面访问动态生成的路由上面
我们再来分析下过程
- 页面被刷新,路由信息被重新计算生成并通过
addRoutes
方法动态添加到了router
当中 addRoutes
方法还没有完成,用户就已经在访问界面了(可以理解为addRoutes
和访问路由同时进行)- 用户一边访问界面,后面一边动态添加路由,
addRoutes
相当于还没有完成就被访问了路由(可以理解访问了一个此刻不存在的路由导致的白屏) - 所以必须要必须要重新访问一次路由才可以解决白屏问题
要怎么解决这个问题?
解决办法
不应该使用
next()
全局前置守卫使用
next({ ...to, replace: true })
next({ ...to});
也是可以的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17next({ ...to, replace: true })中的replace: true
只是一个设置信息,告诉VUE本次操作后,不能通过浏览器后退按钮,返回前一个路由
//换句话说,你使用了replace:true后重新访问了网站
//就不可以通过浏览器来返回页面之前和之后的网站了
举例子:
//比如我刷新之前依次!依次!依次!访问了下面二个网站
网站1: http://localhost:9528/#/product/attr/list
网站2: http://localhost:9528/#/product/spu/list
那么按照平时的来说,我刷新页面依旧可以使用浏览器的前进后退按钮进行跳转了
后退按下,跳转到了网站1,然后此时前进按下,跳转到网站2
//但是如果使用了replace:true
那么刷新网页后就不可以通过前进后退按钮来后退了,之前记录都无效了
动态添加路由,全局前置守卫应该修改成为如下代码(只是示例参考)
- 下面代码是来自vue-element-admin模板当中src\permission.js文件夹的~这里进行了修改举例
1 | //如果token存在 |
为什么next()换为next({…to})(或者next({…to,replace:true}))就可以了,next和这二个区别在哪里
首先我们需要知道路由守卫(全局前置守卫为例子)
先上代码
1
2
3
4
5beforeEach((to, from, next) => {
to // 要去的路由
from // 当前路由
next() // 放行的意思
}代码很简单,但是除了
next()
我们应该还见过next("/")
next("/login")
next({...to})
next({...to,replace:true})
等在路由守卫当中,只有
next()
是放行(放你通过,不会在审核),而next("/")
next("/login")
next({...to})
next({...to,replace:true}
等,都是中断当中的全局前置守卫,执行新的全局前置守卫中断当中的全局前置守卫,执行新的全局前置守卫意思就是会再次调用beforeEach
如下面代码例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14//比如这个,你一定以为是跳转到"/login"就完事了
beforeEach((to, from, next) => {
next('/login')
}
//实际上执行的过程代码
beforeEach((to, from, next) => {
beforeEach(('/logon', from, next) => {
beforeEach(('/logon', from, next) => {
beforeEach(('/logon', from, next) => {
beforeEach... // 一直循环下去...... , 因为我们没有使用 next() 放行
}
}
}
}一直循环下去导致溢出
再来看看这里例子 地址栏输入/home(从哪里来的不重要,我们只需要关注到哪里去)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20beforeEach((to, from, next) => {
//如果目的地址等于 '/home'
//就跳转到 登录地址 '/login'
if(to.path === '/home') {
next('/login')
}
// 如果要去的地方不是 /home ,就放行
else {
next();//放行
}
}
//访问过程如下代码
beforeEach((to, from, next) => {
//进行了中断跳转,会再次调用beforeEach去判断,此时的目的地址是'login'了
beforeEach(('/login', from, next) => {
// 现在要去的地方不是 /home , 因此放行
next();
}
}看看这代码执行的流程图
总结
next()
是放行,不会引发beforeEach再次调用next("/")
next("/login")
next({...to})
next({...to,replace:true})
这些是中断(也就是会再次调用beforeEach),直到执行到了next()才会停止中断
大家可以看看这些全局前置守卫死循环的例子
这些都是死循环,使用就出现Maximum call stack size exceeded
死循环1
1 | router.beforeEach((to, from, next) => { |
死循环2
1 | router.beforeEach((to, from, next) => { |
死循环3
1 | router.beforeEach((to,from,next) =>{ |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 梦洁小站-属于你我的小天地!
评论