vue2的 router在使用过程中遇到的一些问题


Posted in Vue.js onApril 13, 2022

前言

本文记录vue2的vue-router在使用过程中遇到的一些问题。

问题记录

路由守卫的应用

根据路由守卫绑定的位置不同,有下面三种路由守卫

全局守卫

beforeEach/beforeResolve/afterEach

路由独享守卫

beforeEnter

组件内的守卫

beforeRouteEnter/beforeRouteUpdate/beforeRouteLeave

其完整的导航解析过程,看官方文档的说明是这样的:

导航被触发。

在失活的组件里调用 beforeRouteLeave 守卫。

调用全局的 beforeEach 守卫。

在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。

在路由配置里调用 beforeEnter。

解析异步路由组件。

在被激活的组件里调用 beforeRouteEnter。

调用全局的 beforeResolve 守卫 (2.5+)。

导航被确认。

调用全局的 afterEach 钩子。

触发 DOM 更新。

用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

下面是几个常用钩子的实际应用场景:

beforeRouteLeave:跳转页面前,提醒用户,是否保存信息,或者自动为用户保存草稿。

beforeEach:判断是否登录、是否有权限等等,做跳转登录、申请权限、处理权限菜单等操作。

beforeRouteUpdate:重新进入相同页面时,重新初始化、加载数据。

beforeRouteEnter:获取当前页面的前一个页面的信息,比如我们在登录页,登录后要重定向到前一个页面,就可以通过这个钩子获取。注意:这里, 不!能!获取组件实例 this,因为新组件还没有被创建。不过,可以传一个回调,给next来访问实例,在创建好实例后,会执行。

beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通过 `vm` 访问组件实例
  })
}

其他几个路由守卫,我这边不常用,有补充的观众欢迎留下评论。

动态路由实现权限控制

应用场景:管理端根据不同权限,需要展示不同的菜单栏,同时希望没有权限的用户无法访问某些页面。

解决方案:我们在进入路由前,做一个拦截,先判断是否需要处理页面权限,再判断是否已经处理了权限,如果回答都是“是”,我们不需要做处理。否则,请求接口,获取到当前用户的权限菜单,再根据后台返回的信息,给router动态添加路由,再重新进入路由(避免拦截的访问是新添加的路由,出现访问不到的问题)。

具体看下面的伪代码:

router.beforeEach((to, from, next) => {
    if (needAuthority(to.name)) {  //不需要判断权限的页面,不处理
      next()
      return
    } 
    if (alreadyGetAuthorityMenu) {  //已经处理过权限菜单,不再处理
        next()
        return
    }
  
    handleAuthority().then(()=>{
        next({ ...to, replace: true })  //处理权限菜单接口成功,动态路由已经添加了,重新进入路由
      }).catch(() => {
        console.log('请求权限菜单接口错误')
        next()
    })
})

在handleAuthority中我们做了这些事情

  • 判断是否有权限,没有权限的用户,跳转到权限申请页面
  • 根据后台传过来的权限列表,用router.addRoutes(routes: Array)这个API,给router动态添加需要权限控制的页面对应的路由。
  • 给router动态添加一个兜底页面,可以是提示没权限的页面,或者简单一个404页面。

需要注意的是,动态添加路由后,需要next({ ...to, replace: true })重新进入路由,否则,如果拦截的页面路由,是你后面才添加的路由,那新的路由会访问不到。

hash模式的路由参数被干扰

应用场景:比如微信分享链接会加上,类似'?from=singlemessage&isappinstalled=0'这类的参数,当我们使用hash模式路由,同时使用params的方式传参数的时候,常常会被外界的参数干扰到,导致页面无法访问或者参数获取不到,使用动态路由参数是更好的选择。

const router = new VueRouter({
  routes: [
    // 动态路径参数 以冒号开头
    { path: '/user/:id', component: User }
  ]
})
const userId = '123'
// 两种跳转方式
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user

更进一步,我们可以使用props,将组件和路由解耦,在组件中定义id这个props,就能拿到传递的参数。

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User, props: true }
  ]
})

跳转同组件路由,不刷新?

应用场景:跳转同个组件的页面,但是参数不同,期望重新刷新页面。

解决方案:我们可以在beforeRouteUpdate中,重新执行进入页面要执行的代码,但如果需要初始化所有变量,难免有遗漏,更简单的方式是,监听route变化,有变化是 this.$router.go(0)刷新。

// 推荐
beforeRouteUpdate(to, from, next) {
    // 重新加载数据
    next();
},
watch: {
 '$route'(to, from) {
    this.$router.go(0)
 }
}

总结

到此这篇关于Vue router应用问题的文章就介绍到这了!

Vue.js 相关文章推荐
详解vue实现坐标拾取器功能示例
Nov 18 Vue.js
vue打开其他项目页面并传入数据详解
Nov 25 Vue.js
vue3.0中setup使用(两种用法)
Dec 02 Vue.js
vue+elementUI动态增加表单项并添加验证的代码详解
Dec 17 Vue.js
vue 导航守卫和axios拦截器有哪些区别
Dec 19 Vue.js
vue 实现图片懒加载功能
Dec 31 Vue.js
Vue实现图书管理案例
Jan 20 Vue.js
如何在vue中使用video.js播放m3u8格式的视频
Feb 01 Vue.js
使用Vue3+Vant组件实现App搜索历史记录功能(示例代码)
Jun 09 Vue.js
Vue3.0写自定义指令的简单步骤记录
Jun 27 Vue.js
Vue elementUI表单嵌套表格并对每行进行校验详解
Feb 18 Vue.js
vue如何在data中引入图片的正确路径
Jun 05 Vue.js
vue+elementUI实现表格列的显示与隐藏
Apr 13 #Vue.js
如何优化vue打包文件过大
Apr 13 #Vue.js
使用vue判断当前环境是安卓还是IOS
Apr 12 #Vue.js
vue配置型表格基于el-table拓展之table-plus组件
Apr 12 #Vue.js
vue数据字典取键值项目的字典问题
vue报错function () { [native code] },无法出现我们想要的内容 Unknown custom element
vue选项卡切换的实现案例
You might like
PHP实现获取url地址中顶级域名的方法示例
2019/06/05 PHP
常用的javascript function代码
2008/05/23 Javascript
prototype Element学习笔记(篇一)
2008/10/26 Javascript
Js获取事件对象代码
2010/08/05 Javascript
JavaScript的类型转换(字符转数字 数字转字符)
2010/08/30 Javascript
javascript中的一些注意事项 更新中
2010/12/06 Javascript
JavaScript ECMA-262-3 深入解析.第三章.this
2011/09/28 Javascript
利用javascript解决图片缩放及其优化的代码
2012/05/23 Javascript
基于jquery的DIV随滚动条滚动而滚动的代码
2012/07/20 Javascript
html文件中jquery与velocity变量中的$冲突的解决方法
2013/11/01 Javascript
nodejs获取本机内网和外网ip地址的实现代码
2014/06/01 NodeJs
Jquery插件仿百度搜索关键字自动匹配功能
2016/05/11 Javascript
Angularjs 实现分页功能及示例代码
2016/09/14 Javascript
AngularJS 防止页面闪烁的方法
2017/03/09 Javascript
node.js中express中间件body-parser的介绍与用法详解
2017/05/23 Javascript
jQuery实现table中两列CheckBox只能选中一个的示例
2017/09/22 jQuery
JavaScript 保护变量不被随意修改的实现代码
2017/09/27 Javascript
基于vue展开收起动画的示例代码
2018/07/05 Javascript
jQuery事件blur()方法的使用实例讲解
2019/03/30 jQuery
js实现图片区域可点击大小随意改变(适用移动端)代码实例
2019/09/11 Javascript
JS实现页面数据懒加载
2020/02/13 Javascript
vue组件系列之TagsInput详解
2020/05/14 Javascript
使用js原生实现年份轮播选择效果实例
2021/01/12 Javascript
[54:47]Liquid vs VP Supermajor决赛 BO 第五场 6.10
2018/07/05 DOTA
简单的Python2.7编程初学经验总结
2015/04/01 Python
使用PDB简单调试Python程序简明指南
2015/04/25 Python
如何准确判断请求是搜索引擎爬虫(蜘蛛)发出的请求
2015/10/13 Python
解决python删除文件的权限错误问题
2018/04/24 Python
代码实例讲解python3的编码问题
2019/07/08 Python
利用PyQt中的QThread类实现多线程
2020/02/18 Python
Python利用命名空间解析XML文档
2020/08/10 Python
html5 canvas合成海报所遇问题及解决方案总结
2017/08/03 HTML / CSS
教师岗位职责
2013/11/17 职场文书
装修协议书范本
2014/04/21 职场文书
教师外出学习心得体会
2016/01/18 职场文书
2016教师六五普法学习心得体会
2016/01/21 职场文书