vue 解决addRoutes动态添加路由后刷新失效问题


Posted in Javascript onJuly 02, 2018

前言

某些场景下我们需要利用addRoutes动态添加路由,但是刷新后就会失效,前段时间项目里刚好遇到了这个应用场景,所以就花时间研究了一下,做下分享跟记录,说的不对的地方,请大家指正。

应用场景:用户a登录进系统,页面上有个按钮,点击之后会动态添加路由并且跳转,跳转过去之后,用户刷新后也会停留在当前页面。 不点这个按钮,浏览器输入地址,用户会跳到404页面

github:https://github.com/Mrblackant/keepRouter/tree/master

vue 解决addRoutes动态添加路由后刷新失效问题

思路

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动态添加路由刷新不失效功能。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用JavaScript修改CSS属性的代码
May 06 Javascript
JavaScript 函数参数是传值(byVal)还是传址(byRef) 分享
Jul 02 Javascript
jquery选择器、属性设置用法经验总结
Sep 08 Javascript
js文本框输入点回车触发确定兼容IE、FF等
Nov 19 Javascript
详解 javascript中offsetleft属性的用法
Nov 11 Javascript
论JavaScript模块化编程
Mar 07 Javascript
javascript对象的创建和访问
Mar 08 Javascript
原生JS控制多个滚动条同步跟随滚动效果
Dec 22 Javascript
bootstrap table支持高度百分比的实例代码
Feb 28 Javascript
JS实现的合并两个有序链表算法示例
Feb 25 Javascript
JS typeof fn === 'function' &amp;&amp; fn()详解
Aug 22 Javascript
JavaScript 中的执行上下文和执行栈实例讲解
Feb 25 Javascript
vue中的数据绑定原理的实现
Jul 02 #Javascript
Vue实现双向绑定的原理以及响应式数据的方法
Jul 02 #Javascript
jsonp跨域获取数据的基础教程
Jul 01 #Javascript
vue + webpack如何绕过QQ音乐接口对host的验证详解
Jul 01 #Javascript
关于Vue组件库开发详析
Jul 01 #Javascript
D3.js实现拓扑图的示例代码
Jun 30 #Javascript
详解angular如何调用HTML字符串的方法
Jun 30 #Javascript
You might like
全国FM电台频率大全 - 28 甘肃省
2020/03/11 无线电
第七节 类的静态成员 [7]
2006/10/09 PHP
php curl 登录163邮箱并抓取邮箱好友列表的代码(经测试)
2011/04/07 PHP
用php解析html的实现代码
2011/08/08 PHP
php检查字符串中是否有外链的方法
2015/07/29 PHP
php等比例缩放图片及剪切图片代码分享
2016/02/13 PHP
PHP语言对接抖音快手小红书视频/图片去水印API接口源码
2020/08/11 PHP
js操作table示例(个人心得)
2013/11/29 Javascript
jsPDF导出pdf示例
2014/05/02 Javascript
一款由jquery实现的整屏切换特效
2014/09/15 Javascript
jquery代码实现多选、不同分享功能
2015/07/31 Javascript
JS获取子窗口中返回的数据实现方法
2016/05/28 Javascript
利用js定义一个导航条菜单
2017/03/14 Javascript
div中文字内容溢出常见的解决方法
2017/03/16 Javascript
Angular.js中控制器之间的传值详解
2017/04/24 Javascript
关于页面刷新vuex数据消失问题解决方案
2017/07/03 Javascript
使用Object.defineProperty如何巧妙找到修改某个变量的准确代码位置
2018/11/02 Javascript
Vue表单绑定的实例代码(单选按钮,选择框(单选时,多选时,用 v-for 渲染的动态选项)
2019/05/13 Javascript
深入了解query和params的使用区别
2019/06/24 Javascript
Vue 实现输入框新增搜索历史记录功能
2019/10/15 Javascript
[01:08:24]DOTA2-DPC中国联赛 正赛 RNG vs Phoenix BO3 第一场 2月5日
2021/03/11 DOTA
Python字典操作简明总结
2015/04/13 Python
Python图形绘制操作之正弦曲线实现方法分析
2017/12/25 Python
Python进程间通信Queue消息队列用法分析
2019/05/22 Python
使用python os模块复制文件到指定文件夹的方法
2019/08/22 Python
python 利用turtle库绘制笑脸和哭脸的例子
2019/11/23 Python
Python使用pyenv实现多环境管理
2021/02/05 Python
捷克建筑材料网上商店:DEK.cz
2021/03/06 全球购物
声明struct x1 { . . . }; 和typedef struct { . . . }x2;有什么不同
2012/06/02 面试题
STP的判定过程
2012/10/01 面试题
军训学生自我鉴定
2014/02/12 职场文书
瘦西湖导游词
2015/02/03 职场文书
生产车间主任岗位职责
2015/04/08 职场文书
Python如何把不同类型数据的json序列化
2021/04/30 Python
python图片灰度化处理的几种方法
2021/06/23 Python
python井字棋游戏实现人机对战
2022/04/28 Python