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项目如何引入bootstrap、elementUI、echarts
Nov 26 Vue.js
vue3.0+vue-router+element-plus初实践
Dec 02 Vue.js
如何正确解决VuePress本地访问出现资源报错404的问题
Dec 03 Vue.js
Vue3 实现双盒子定位Overlay的示例
Dec 22 Vue.js
vue中父子组件的参数传递和应用示例
Jan 04 Vue.js
vue3.0中友好使用antdv示例详解
Jan 05 Vue.js
vue+elementui通用弹窗的实现(新增+编辑)
Jan 07 Vue.js
vue二选一tab栏切换新做法实现
Jan 19 Vue.js
vue 项目@change多个参数传值多个事件的操作
Jan 29 Vue.js
vue实现拖拽进度条
Mar 01 Vue.js
vue 使用饿了么UI仿写teambition的筛选功能
Mar 01 Vue.js
vue项目实现分页效果
Mar 24 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安装全攻略:APACHE
2006/10/09 PHP
一个基于PDO的数据库操作类
2011/03/24 PHP
php读取文件内容的三种可行方法示例介绍
2014/02/08 PHP
tp5框架无刷新分页实现方法分析
2019/09/26 PHP
解决在Laravel 中处理OPTIONS请求的问题
2019/10/11 PHP
JQuery以JSON方式提交数据到服务端示例代码
2014/05/05 Javascript
javascript实现阻止iOS APP中的链接打开Safari浏览器
2014/06/12 Javascript
基于jQuery实现复选框的全选 全不选 反选功能
2014/11/24 Javascript
jquery实现的横向二级导航效果代码
2015/08/26 Javascript
关于 jQuery Easyui异步加载tree的问题解析
2016/12/06 Javascript
Vue.js实现微信过渡动画左右切换效果
2017/06/13 Javascript
Angular4编程之表单响应功能示例
2017/12/13 Javascript
详解微信JS-SDK选择图片遇到的坑
2018/08/15 Javascript
详解vue beforeRouteEnter 异步获取数据给实例问题
2019/08/09 Javascript
layer页面跳转,获取html子节点元素的值方法
2019/09/27 Javascript
jQuery实现图片切换效果
2020/10/19 jQuery
[00:32]2018DOTA2亚洲邀请赛出场——LGD
2018/04/04 DOTA
利用Python开发微信支付的注意事项
2016/08/19 Python
python之文件的读写和文件目录以及文件夹的操作实现代码
2016/08/28 Python
使用Django Form解决表单数据无法动态刷新的两种方法
2017/07/14 Python
Python编程给numpy矩阵添加一列方法示例
2017/12/04 Python
Python搭建FTP服务器的方法示例
2018/01/19 Python
python 读取视频,处理后,实时计算帧数fps的方法
2018/07/10 Python
django如何连接已存在数据的数据库
2018/08/14 Python
在pandas多重索引multiIndex中选定指定索引的行方法
2018/11/16 Python
django-rest-framework解析请求参数过程详解
2019/07/18 Python
python_array[0][0]与array[0,0]的区别详解
2020/02/18 Python
HTML5实践-图片设置成灰度图
2012/11/12 HTML / CSS
Myprotein法国官网:欧洲第一运动营养品牌
2019/03/26 全球购物
Marc O’Polo俄罗斯官方在线商店:德国高端时尚品牌
2019/12/26 全球购物
减负增效提质方案
2014/05/23 职场文书
社区活动策划方案
2014/08/21 职场文书
村主任群众路线个人对照检查材料
2014/09/26 职场文书
安全生产工作汇报
2014/10/28 职场文书
酒店开业主持词
2015/07/02 职场文书
Java spring定时任务详解
2021/10/05 Java/Android