Vue router 应用问题记录
前言
本文记录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之组件化(二)
- 不用React Vue,只用原生JS,如何开发单页面应用?
- Vue单页面应用
- JS之在Vue对象内部获取vue对象的索引(箭头函数的闭包导致this代表的是函数本身)「建议收藏」
- html使用vue axios,使用 Vue和axios
- 使用 vue 创建你的第一个 PWA 应用
- 【说站】超级容易上手,Vue中使用JSX
- vue分页组件动态页码_怎样分页设置页码
- VUE双向绑定原理_vue的数据绑定怎么实现
- Vue基础-插值表达式-数据驱动视图-指令系统
- VUE 初学者基础知识
- vue cli 3 升级到 vue cli 4 方法步骤及升级点总结「建议收藏」
- vue组件间通信
- 2023前端vue面试题及答案_2023-02-28
- 微擎独立后台TP5+VUE分离+小程序
- 4. 「vue@2.6.11 源码分析」new Vue() 整体流程和组件渲染之前的准备工作
- Vue中ref和$refs的介绍及使用
- vue.js入门篇之Vue.js 样式绑定
- vue attribute中使用字符串模板 template string详解编程语言
- Vue抢跑Redis速度感受实时重磅数据(vue获取redis)
- 从零开始Vue项目中使用Redis(vue使用redis)