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 相关文章推荐
element-plus一个vue3.xUI框架(element-ui的3.x 版初体验)
Dec 02 Vue.js
vue实现图片裁剪后上传
Dec 16 Vue.js
Vuex实现简单购物车
Jan 10 Vue.js
vue自定义组件实现双向绑定
Jan 13 Vue.js
Vue 3自定义指令开发的相关总结
Jan 29 Vue.js
如何让vue长列表快速加载
Mar 29 Vue.js
vue-element-admin项目导入和导出的实现
May 21 Vue.js
详解Vue项目的打包方式(生成dist文件)
Jan 18 Vue.js
vue cli4中mockjs在dev环境和build环境的配置详情
Apr 06 Vue.js
vue实现书本翻页动画效果实例详解
Apr 08 Vue.js
vue 数字翻牌器动态加载数据
Apr 20 Vue.js
vue实现省市区联动 element-china-area-data插件
Apr 22 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
redis+php实现微博(二)发布与关注功能详解
2019/09/23 PHP
javascript来定义类的规范小结
2010/11/19 Javascript
JS将数字转换成三位逗号分隔的样式(示例代码)
2014/02/19 Javascript
使用ajax+jqtransform实现动态加载select
2014/12/01 Javascript
jQuery插件pagination实现分页特效
2015/04/12 Javascript
JavaScript操作HTML元素和样式的方法详解
2015/10/21 Javascript
解决微信浏览器Javascript无法使用window.location.reload()刷新页面
2016/06/21 Javascript
微信小程序 教程之小程序配置
2016/10/17 Javascript
清除js缓存的多种方法总结
2016/12/09 Javascript
Vue.js双向绑定操作技巧(初级入门)
2016/12/27 Javascript
详解JavaScript中js对象与JSON格式字符串的相互转换
2017/02/14 Javascript
详解创建自定义的Angular Schematics
2018/06/06 Javascript
javascript中UMD规范的代码推演
2018/08/29 Javascript
浅谈Vue 性能优化之深挖数组
2018/12/11 Javascript
浅谈vue中使用编辑器vue-quill-editor踩过的坑
2020/08/03 Javascript
谈谈JavaScript令人迷惑的==与+
2020/08/31 Javascript
解决vue prop传值default属性如何使用,为何不生效的问题
2020/09/21 Javascript
[36:16]完美世界DOTA2联赛PWL S3 access vs Rebirth 第一场 12.19
2020/12/24 DOTA
python射线法判断一个点在图形区域内外
2019/06/28 Python
Django框架表单操作实例分析
2019/11/04 Python
如何利用python生成MD5并去重
2020/12/07 Python
matplotlib之多边形选区(PolygonSelector)的使用
2021/02/24 Python
美国林业供应商:Forestry Suppliers
2019/05/01 全球购物
Everlast官网:拳击、综合格斗和健身相关的体育用品
2020/08/03 全球购物
日本最大的彩色隐形眼镜销售网站:CharmColor
2020/09/09 全球购物
应届生财务会计求职信
2013/11/05 职场文书
土木工程专业个人求职信
2013/12/05 职场文书
寄语是什么意思
2014/04/10 职场文书
领导班子党的群众路线对照检查材料
2014/09/25 职场文书
少年雷锋观后感
2015/06/10 职场文书
学校运动会简讯
2015/07/20 职场文书
2016春季运动会开幕词
2016/03/04 职场文书
解除租赁合同协议书
2016/03/21 职场文书
少年的你:世界上没有如果,要在第一次就勇敢的反抗
2019/11/20 职场文书
JS + HTML 罗盘式时钟的实现
2021/05/21 Javascript