一. 路由钩子语法
在 vue-router 的官方文档中, 将路由钩子翻译为导航守卫, 下面是文档中的内容摘要, 大家也可以通过传送门 https://router.vuejs.org/zh-cn/advanced/navigation-guards.html 前往官网阅读详细内容
路由钩子
路由钩子主要是给使用者在路由发生变化时进行一些特殊的处理而定义的, 靠.. 好拗口啊.
总体来讲 vue 里面提供了三大类钩子
1, 全局钩子
2, 某个路由独享的钩子
3, 组件内钩子
三种路由钩子中都涉及到了三个参数, 这里直接上官方介绍吧
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子. 执行效果依赖 next 方法的调用参数.
next(): 进行管道中的下一个钩子. 如果全部钩子执行完了, 则导航的状态就是 confirmed (确认的).
next(false): 中断当前的导航. 如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮), 那么 URL 地址会重置到 from 路由对应的地址.
next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址. 当前的导航被中断, 然后进行一个新的导航.
(一). 全局守卫 (全局路由钩子)
你可以使用 router.beforeEach 注册一个全局前置守卫:
- const router = new VueRouter({ ... })
- router.beforeEach((to, from, next) => {
- // ...
- next()
- })
每个守卫方法接受三个参数:
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子. 执行效果依赖 next 方法的调用参数
注意: 使用全局路由钩子, 一定要调用 next()!!!
(二). 路由独享的守卫 (路由内钩子)
你可以在路由配置上直接定义 beforeEnter 守卫:
- const router = new VueRouter({
- routes: [
- {
- path: '/foo',
- component: Foo,
- beforeEnter: (to, from, next) => {
- // ...
- }
- }
- ]
- })
这些守卫与全局前置守卫的方法参数是一样的.
(三). 组件内的守卫 (组件内钩子)
最后, 你可以在路由组件中直接定义一下路由导航守卫:
- beforeRouteEnter
- beforeRouteUpdate (2.2 新增)
- beforeRouteLeave
- const Foo = {
- template: `...`,
- beforeRouteEnter (to, from, next) {
- // 在渲染该组件的对应路由被 confirm 前调用
- // 不! 能! 获取组件实例 `this`
- // 因为当守卫执行前, 组件实例还没被创建
- },
- beforeRouteUpdate (to, from, next) {
- // 在当前路由改变, 但是该组件被复用时调用
- // 举例来说, 对于一个带有动态参数的路径 /foo/:id, 在 /foo/1 和 /foo/2 之间跳转的时候,
- // 由于会渲染同样的 Foo 组件, 因此组件实例会被复用. 而这个钩子就会在这个情况下被调用.
- // 可以访问组件实例 `this`
- },
- beforeRouteLeave (to, from, next) {
- // 导航离开该组件的对应路由时调用
- // 可以访问组件实例 `this`
- }
- }
二. 路由钩子在实际开发中的应用场景
路由钩子在实际的开发过程中使用较少, 我在实际的项目中只在组件内使用过 beforeRouteLeave, 使用场景分别为一下三类情况:
(一) 清除当前组件中的定时器
当一个组件中有一个定时器时, 在路由进行切换的时候, 可使用 beforeRouteLeave 将定时器进行清楚, 以免占用内存:
- beforeRouteLeave (to, from, next) {
- window.clearInterval(this.timer) // 清楚定时器
- next()
- }
(二) 当页面中有未关闭的窗口, 或未保存的内容时, 阻止页面跳转
如果页面内有重要的信息需要用户保存后才能进行跳转, 或者有弹出框的情况. 应该阻止用户跳转
- beforeRouteLeave (to, from, next) {
- // 判断是否弹出框的状态和保存信息与否
- if (this.dialogVisibility === true) {
- this.dialogVisibility = false // 关闭弹出框
- next(false) // 回到当前页面, 阻止页面跳转
- }else if(this.saveMessage === false) {
- alert('请保存信息后退出!') // 弹出警告
- next(false) // 回到当前页面, 阻止页面跳转
- }else {
- next() // 否则允许跳转
- }
- }
(三) 保存相关内容到 Vuex 中或 Session 中
当用户需要关闭页面时, 可以将公用的信息保存到 session 或 Vuex 中
- beforeRouteLeave (to, from, next) {
- localStorage.setItem(name, content); // 保存到 localStorage 中
- next()
- }
来源: https://juejin.im/entry/5ae9c27951882567147d3216