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 element-ul实现展开和收起功能的实例代码
Nov 25 Vue.js
vue的hash值原理也是table切换实例代码
Dec 14 Vue.js
vue 在服务器端直接修改请求的接口地址
Dec 19 Vue.js
vue实现简易的双向数据绑定
Dec 29 Vue.js
基于Vue2实现移动端图片上传、压缩、拖拽排序、拖拽删除功能
Jan 05 Vue.js
vue3.0 自适应不同分辨率电脑的操作
Feb 06 Vue.js
用vite搭建vue3应用的实现方法
Feb 22 Vue.js
Vue接口封装的完整步骤记录
May 14 Vue.js
Vue项目打包、合并及压缩优化网页响应速度
Jul 07 Vue.js
如何用vue实现网页截图你知道吗
Nov 17 Vue.js
解决vue-router的beforeRouteUpdate不能触发
Apr 14 Vue.js
Vue组件化(ref,props, mixin,.插件)详解
May 15 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 向右侧拉菜单实现代码,测试使用中
2009/11/03 PHP
探讨Hessian在PHP中的使用分析
2013/06/13 PHP
Drupal7连接多个数据库及常见问题解决
2014/03/02 PHP
php单链表实现代码分享
2016/07/04 PHP
php进行md5加密简单实例方法
2019/09/19 PHP
加载远程图片时,经常因为缓存而得不到更新的解决方法(分享)
2013/06/26 Javascript
js获取网页可见区域、正文以及屏幕分辨率的高度
2014/05/15 Javascript
JavaScript window.location对象
2014/11/14 Javascript
javascript数据类型示例分享
2015/01/19 Javascript
Grunt入门教程(自动任务运行器)
2015/08/06 Javascript
基于jQuery实现左右图片轮播(原理通用)
2015/12/24 Javascript
javascript正则表达式定义(语法)总结
2016/01/08 Javascript
javascript实现在网页中运行本地程序的方法
2016/02/03 Javascript
不使用script导入js文件的几种方法
2016/10/27 Javascript
js调用父框架函数与弹窗调用父页面函数的简单方法
2016/11/01 Javascript
深入理解Javascript中的valueOf与toString
2017/01/04 Javascript
图文介绍Vue父组件向子组件传值
2018/02/17 Javascript
Element UI 自定义正则表达式验证方法
2018/09/04 Javascript
实例讲解JavaScript截取字符串
2018/11/30 Javascript
jQuery实现文本显示一段时间后隐藏的方法分析
2019/06/20 jQuery
JavaScript判断数据类型有几种方法及区别介绍
2020/09/02 Javascript
js实现3D粒子酷炫动态旋转特效
2020/09/13 Javascript
Python基于有道实现英汉字典功能
2015/07/25 Python
Python开发SQLite3数据库相关操作详解【连接,查询,插入,更新,删除,关闭等】
2017/07/27 Python
python去重,一个由dict组成的list的去重示例
2019/01/21 Python
python3实现逐字输出的方法
2019/01/23 Python
Python基于opencv调用摄像头获取个人图片的实现方法
2019/02/21 Python
Django为窗体加上防机器人的验证码功能过程解析
2019/08/14 Python
DRF框架API版本管理实现方法解析
2020/08/21 Python
如何避免常见的6种HTML5错误用法
2017/11/06 HTML / CSS
史泰博(Staples)中国官方网站:办公用品一站式采购
2016/09/05 全球购物
教学个人的自我评价分享
2014/02/16 职场文书
应届毕业生求职信范文
2014/05/08 职场文书
讲文明树新风演讲稿
2014/05/12 职场文书
2015年毕业实习工作总结
2015/05/29 职场文书
《攀登者》:“海拔8000米以上,你不能指望任何人”
2019/11/25 职场文书