vue 解决addRoutes动态添加路由后,刷新失效问题
你是电,你是光,你是最美的太阳🌞
前言
某些场景下我们需要利用addRoutes动态添加路由,但是刷新后就会失效,前段时间项目里刚好遇到了这个应用场景,所以就花时间研究了一下,做下分享跟记录,说的不对的地方,请大家指正。
应用场景:用户a登录进系统,页面上有个按钮,点击之后会动态添加路由并且跳转,跳转过去之后,用户刷新后也会停留在当前页面。 不点这个按钮,浏览器输入地址,用户会跳到404页面
github:https://github.com/Mrblackant...
在线查看:http://an888.net/router/keepR...
思路
1.用户点击按钮,用addRutes动态添加路由并跳转,并把路由保存;
2.用户在新跳转的页面,刷新时利用beforeEach进行拦截判断,如果发现之前有保存路由,并且判断新页面只是刷新事件,再将之前保存的路由添加进来;
代码
1.按钮点击,保存路由并跳转
(1).在router/index.js里声明一个数组,里边是一些固定的路由,比如你的登录页面、404等等
//router/index.js
export const constantRouterMap=[
{
path: '/',
// name: 'HelloWorld',
component: HelloWorld
}
]
Vue.use(Router)
export default new Router({
routes: constantRouterMap
})
(2).按钮点击,跳转、保存路由;
注意,保存路由这一步骤,要做进要跳转到的组件里,这是为了防止在beforeEach拦截这边产生死循环
添加路由需要两点,一是path,二是component,你可以封装成方法,看着就会简洁一点,我这里就不做了
记得要用concat方法连接,固定的路由和动态新加的路由,这样浏览器回退的时候也能正常返回
//点击跳转
<template>
<div>
点击新增 动态路由: "secondRouter"
<br/>
<el-button @click="srouter" type="primary">新增动态路由</el-button>
</div>
</template>
<script>
import router from 'vue-router'
import {constantRouterMap} from '@/router'
export default {
name: 'kk',
mounted(){
},
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
methods:{
srouter(){
let newRoutes=constantRouterMap.concat([{path:'/secondRouter',
component :resolve => require(["@/components/kk"], resolve )
}])
this.$router.addRoutes(newRoutes)
this.$router.push({path:'/secondRouter'})
}
}
}
</script>
//跳转过去的component组件,xxx.vue
<template>
<div class="secondRoute">
恭喜你,动态添加路由成功,浏览器的链接已经变化;
<h3>无论你怎么刷新我都会留在当前页面</h3>
<h3>并且点击浏览器回退键,我会跳到之前页面,不会循环</h3>
</div>
</template>
<script>
import router2 from '@/router'
import router from 'vue-router'
export default {
name: 'HelloWorld',
mounted(){
localStorage.setItem('new',JSON.stringify({'path':'/secondRouter','component':'kk'}))//保存路由
},
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
methods:{
}
}
</script>
2.路由拦截beforeEach
这里拦截的时候,就判断localStorage里边有没有保存新的动态路由,如果有,就进行判断,逻辑处理,处理完之后就把保存的路由清除掉,防止进入死循环。
进入第一层判断后,需要再次判断一下是不是页面的刷新事件
import router from './router'
import { constantRouterMap } from '@/router' //router里的固定路由
router.beforeEach((to, from, next) => {
if (localStorage.getItem('new')) {
var c = JSON.parse(localStorage.getItem('new')),
lastUrl=getLastUrl(window.location.href,'/');
if (c.path==lastUrl) { //动态路由页面的刷新事件
let newRoutes = constantRouterMap.concat([{
path: c.path,
component: resolve => require(["@/components/" + c.component + ""], resolve)
}])
localStorage.removeItem('new')
router.addRoutes(newRoutes)
router.replace(c.path) //replace,保证浏览器回退的时候能直接返回到上个页面,不会叠加
}
}
next()
})
var getLastUrl=(str,yourStr)=>str.slice(str.lastIndexOf(yourStr))//取到浏览器出现网址的最后"/"出现的后边的字符
ps:一开始我还以为匹配不到路由跳转404要在拦截这里处理,后来发现根本不用,直接在注册路由的时候加上下边两段就行了:
export const constantRouterMap = [{
path: '/',
component: HelloWorld
},
{//404
path: '/404',
component: ErrPage
},
{ //重定向到404
path: '*', redirect: '/404' }
]
整体的思路大概就是这样,主要就是利用了beforeEach拦截+localStorage的数据存储,就能完成,addRoutes动态添加路由刷新不失效功能。
不足的地方还请大家多多指正
推荐阅读
mpvue写小程序遇到的问题总结(自己用mpvue实现一个小程序的tabbar,vantUi的使用)
公司要开发一个小程序,面向用户分为3种角色,所以要自己手写个tabbar(文章编辑中,届时将链接放过来)因为也是时隔很久写小程序,就选择了跟vue相近的mpvue来写,或多或少也遇到了点问题,现总结一下。
大师兄赞 5阅读 5.4k评论 4
ESlint + Stylelint + VSCode自动格式化代码(2023)
安装插件 ESLint,然后 File -> Preference-> Settings(如果装了中文插件包应该是 文件 -> 选项 -> 设置),搜索 eslint,点击 Edit in setting.json
谭光志赞 34阅读 20.7k评论 9
vue UI框架比较
最好基于vue2.0PC端:因为用过的是饿了么UI,所以比较以饿了么UI为基础element UI 饿了么UI支持vue2.x80分优点:组件的API方法、属性等封装的较为完善缺点:样式有些生硬,不够炫酷美观N3 N3支持vue2.x70分优点:...
chinawzc赞 22阅读 39.8k评论 17
【已结束】SegmentFault 思否写作挑战赛!
SegmentFault 思否写作挑战赛 是思否社区新上线的系列社区活动在 2 月 8 日 正式面向社区所有用户开启;挑战赛中包含多个可供作者选择的热门技术方向,根据挑战难度分为多个等级,快来参与挑战,向更好的自己前进!
SegmentFault思否赞 20阅读 5.6k评论 10
Vue2 导出excel
2020-07-15更新 excel导出安装 {代码...} src文件夹下新建一个libs文件夹,新建一个excel.js {代码...} vue页面中使用 {代码...} ===========================以下为早期的文章今天在开发的过程中需要做一个Vue的...
原谅我一生不羁放歌搞文艺赞 14阅读 20k评论 9
用了那么久的 SVG,你还没有入门吗?
其实在大部分的项目中都有 直接 或 间接 使用到 SVG 和 Canvas,但是在大多数时候我们只是选择 简单了解 或 直接跳过,这有问题吗?没有问题,毕竟砖还是要搬的!
熊的猫赞 17阅读 1.6k评论 2
嘿,vue中keep-alive有个「大坑」你可能还不知道
背景是这样的,我们使用vue2开发一个在线客服使用的IM应用,基本布局是左边是访客列表,右边是访客对话,为了让对话加载更友好,我们将对话的路由使用<keep-alive>缓存起来。但是如果将所有对话都缓存,未...
wuwhs赞 12阅读 2.6k
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。