深入理解Vue 的钩子函数

说到Vue的钩子函数,可能很多人只停留在一些很简单常用的钩子( created , mounted ),而且对于里面的区别,什么时候该用什么钩子,并没有仔细的去研究过,且Vue的生命周期在面试中也算是比较高频的考点,那么该如何回答这类问题,让人有眼前一亮的感觉呢...

Vue-Router导航守卫

有的时候,我们需要通过路由来进行一些操作,比如最常见的登录权限验证,当用户满足条件时,才让其进入导航,否则就取消跳转,并跳到登录页面让其登录。

为此我们有很多种方法可以植入路由的导航过程: 全局的, 单个路由独享的, 或者组件级的 , 推荐优先阅读官方路由文档

全局守卫

vue-router全局有三个守卫:

router.beforeEach 全局前置守卫 进入路由之前

router.beforeResolve 全局解析守卫(2.5.0+) 在beforeRouteEnter调用之后调用

router.afterEach 全局后置钩子 进入路由之后

使用方法:

// main.js 入口文件 import router from './router' ; // 引入路由 router . beforeEach (( to , from , next ) => { next (); }); router . beforeResolve (( to , from , next ) => { next (); }); router . afterEach (( to , from ) => { console . log ( 'afterEach 全局后置钩子' ); });

to,from,next 这三个参数:

to和from是 将要进入和将要离开的路由对象 ,路由对象指的是平时通过this.$route获取到的路由对象。

next:Function这个参数是个函数,且 必须调用,否则不能进入路由 (页面空白)。

next() 进入该路由。

next(false): 取消进入路由,url地址重置为from路由地址(也就是将要离开的路由地址)。

next 跳转新路由,当前的导航被中断,重新开始一个新的导航。

我们可以这样跳转:next('path地址') 或者 next({path:''}) 或者 next({name:''}) 且允许设置诸如 replace: true、name: 'home' 之类的选项 以及你用在router-link或router.push的对象选项。

路由独享守卫

如果你不想全局配置守卫的话,你可以为某些路由单独配置守卫:

const router = new VueRouter({ routes : [ { path : '/foo' , component : Foo , beforeEnter : ( to , from , next ) => { // ... } } ] })

路由组件内的守卫:

beforeRouteEnter 进入路由前

beforeRouteUpdate (2.2) 路由复用同一个组件时

beforeRouteLeave 离开当前路由时

文档中的介绍:

beforeRouteEnter (to, from, next) { }, beforeRouteUpdate ( to , from , next ) { // 在当前路由改变,但是该组件被复用时调用 可以访问组件实例 `this` }, beforeRouteLeave ( to , from , next ) { // 导航离开该组件的对应路由时调用,可以访问组件实例 `this` }

beforeRouteEnter访问this

因为钩子在组件实例还没被创建的时候调用,所以不能获取组件实例 this ,可以通过传一个回调给 next 来访问组件实例 。

但是 回调的执行时机在mounted后面 ,所以在我看来这里对this的访问意义不太大,可以放在 created 或者 mounted 里面。

beforeRouteEnter (to, from, next) { console . log ( '在路由独享守卫后调用' ); next ( vm => { // 通过 `vm` 访问组件实例`this` 执行回调的时机在mounted后面, }) }

beforeRouteLeave:

导航离开该组件的对应路由时调用,我们用它来禁止用户离开,比如还未保存草稿,或者在用户离开前,将 setInterval 销毁,防止离开之后,定时器还在调用。

beforeRouteLeave (to, from , next) { if ( 文章保存 ) { next (); // 允许离开或者可以跳到别的路由 上面讲过了 } else { next ( false ); // 取消离开 } }

关于钩子的一些知识:

路由钩子函数的错误捕获

如果我们在全局守卫/路由独享守卫/组件路由守卫的钩子函数中有错误,可以这样捕获:

router.onError(callback => { // 2.4.0新增 并不常用,了解一下就可以了 console . log ( callback , 'callback' ); });

在路由文档中还有更多的实例方法:动态添加路由等,有兴趣可以了解一下。

跳转死循环,页面永远空白

我了解到的,很多人会碰到这个问题,来看一下这段伪代码:

router.beforeEach((to, from, next) => { if ( 登录 ){ next () } else { next ({ name : 'login' }); } });

看逻辑貌似是对的,但是当我们跳转到 login 之后,因为此时还是未登录状态,所以会一直跳转到 login 然后死循环,页面一直是空白的,所以:我们需要把判断条件稍微改一下。

if(登录 || to.name === 'login'){ next() } // 登录,或者将要前往login页面的时候,就允许进入路由
全局后置钩子的跳转:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/4a11ae274cd315f626018742c4f5ac91.html