Vue.js - 路由 vue-router 的使用详解3(导航钩子函数:在路由改变前后触发)
有时我们需要在页面发生路由改变时,进行一些操作。比如从一个页面过渡到另一页面时,显示一个全局的 Loading 动画。或者进入某页面时对用户权限进行校验。
(3)beforeEach() 方法还有个常用的地方:验证用户权限。
(2)afterEach() 方法有个常用的地方是自动让页面返回最顶端。
这些通过 vue-router 提供的导航钩子就可以实现。我们可以在如下 3 个地方使用钩子函数。
一、全局的钩子函数
1,路由改变前的钩子
(1)通过路由对象的 beforeEach() 方法调用。
beforeEach() 方法三个参数介绍:
(1)to:即将要进入的目标路由对象。
(2)frome:当前导航正要离开的路由对象。
(3)next:路由的控制参数,有如下四种调用方式:
(1)to:即将要进入的目标路由对象。
(2)frome:当前导航正要离开的路由对象。
(3)next:路由的控制参数,有如下四种调用方式:
- next():如果一切正常,则调用这个方法进入下一个钩子。
- next(false):取消导航(即路由不发生改变)
- next('/login'):当前的导航被中断,然后进行一个新的导航(路径可自由指定)。
- next(error):如果一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
const router = new Router({ ... }) router.beforeEach((to, from, next) => { // ... })
(2)下面是完整的样例:
import Vue from 'vue' import Router from 'vue-router' import index from '@/components/index' //引入首页组件 import hello from '@/components/hello' //引入欢迎页组件 //Vue全局使用Router Vue.use(Router) const router = new Router({ routes: [ //配置路由,使用数组形式 { path: '/', //链接路径 name: 'index', //路由名称 component: index//映射的组件 }, { path: '/hello', name: 'hello', component: hello } ] }) //全局路由改变前钩子 router.beforeEach((to, from, next) => { console.log('即将进入:', to); console.log('即将离开:', from); next(); }) export default router
(3)beforeEach() 方法还有个常用的地方:验证用户权限。
- 比如某些页面需要先验证是否登录,如果登录了就可以访问,否则跳转到登录页。这个判断就可以放在 beforeEach() 方法中进行。
//全局路由改变前钩子 router.beforeEach((to, from, next) => { //这里简单地使用localStorage来判断是否登陆 if(window.localStorage.getItem('token')){ next(); }else{ next('/login'); } })
2,路由改变后的钩子
(1)通过路由对象的 afterEach() 方法调用。它和上面的 beforeEach() 方法相比,少了 next 参数。
//全局路由改变后钩子 router.afterEach((to, from) => { console.log('即将进入:', to); console.log('即将离开:', from); })
(2)afterEach() 方法有个常用的地方是自动让页面返回最顶端。
- 比如一个页面较长,滚动到某个位置后跳转。这时另一个页面滚动条默认是上一个页面停留的位置。我们可以在 afterEach() 方法中将滚动条位置进行重置。
//全局路由改变后钩子 router.afterEach((to, from) => { //将滚动条恢复到最顶端 window.scrollTo(0, 0); })
二、路由配置中的钩子函数
在路由配置文件中我们只能设置路由改变前的钩子函数(beforeEnter),不能设置改变后的钩子(afterEach)
const router = new Router({ routes: [ //配置路由,使用数组形式 { path: '/', //链接路径 name: 'index', //路由名称 component: index //映射的组件 }, { path: '/hello', name: 'hello', component: hello, beforeEnter:(to,from,next)=>{ console.log('即将进入:', to); console.log('即将离开:', from); next(); } } ] })
三、组件内的钩子函数
1,钩子函数介绍
(1)beforeRouteEnter (to, from, next)
- 在该组件的对应路由被 confirm 前调用。(即路由进入前调用)
- 由于此时实例还没被创建,所以此时不能获取组件实例(this)。
(2)beforeRouteUpdate (to, from, next)
- 在当前路由改变,但是该组件被复用时调用。比如:我们在一个带有动态参数的路径 /hello/:id 之间跳转(/hello/1 和 /hello/2),虽然渲染的是同样的 Detail 组件,但这个钩子还是会被调用。
- 该函数内可以访问获取组件实例(this)。
(3)beforeRouteLeave (to, from, next)
- 当导航离开该组件的对应路由时调用。(即路由离开前调用)
- 该函数内可以访问获取组件实例(this)。
2,使用样例
下面样例我们可以在路由发生变化时,动态地改变网页标题。
<template> <div> <h1>ID:{{ $route.params.id}}</h1> <h1>用户名:{{ $route.params.userName}}</h1> </div> </template> <script> export default { //路由进入前调用 beforeRouteEnter (to, from, next) { window.document.title = "欢迎页"; next(); }, } </script>
附:使用 watch 监测路由变化
除了使用钩子函数外,我们也可以使用 watch 来监听 $route 对象,然后根据路由参数的变化来进行响应。<template> <div id="app"> <keep-alive> <router-view/> </keep-alive> </div> </template> <script> export default { name: 'App', watch: { '$route' (to, from) { // 对路由变化作出响应... } } } </script>