以前给你们分享了利用keep-alive进行缓存你想要的页面,而后到后面会出现这样的问题:
我有三个组件A(组件)、B(A中的弹框)、C(组件),其实算是两个组件,一个弹框,如今他们的关系是这样的:
点击A(li循环列表组件)中某个功能,弹出了B(弹框-表格),而后在B(弹框)点击链接跳转到C(组件)。
而后我想要实现A(li循环列表组件)缓存,B(弹框-表格)根据A的传参实时刷新,C(组件)根据B的传参实时刷新,A->B->C。
接下来返回依次从C->B->A,以下图:html
一、B是一个弹框,和A处于同一个组件,从C返回要看到B的话,就要实现A缓存,即C返回A的时候A没刷新还保持弹框不变就能够实现C是退回B,这个用前面说的keep-alive就能够实现。
二、这时候从B->A(咱们这边退回按钮设置关闭弹框是能够实现B->A的),点击的是浏览器或者手机的回退键,就会发现,并无实现这一步,而是B直接退到A的前一页,由于系统的回退键记录的是历史路由,而B和A自己就是一个路由,因此就会出现这种状况。
这时候的解决办法就是:判断路由离开前,B弹框是否打开,如果打开就先关闭弹框,不容许路由跳转,因此就能够形成B回退到A的假象。这时候利用的是beforeRouteLeave钩子。实现以下:vue
beforeRouteLeave(to,from,next) { //B是B弹框的v-model值 if (this.B) { this.B= false; next(false); } else { next(); } }
三、而后接下来你就会发现另外一个问题,就是B->C的时候,由于B是打开的,上面的判断就会形成B没法跳转到C,可是没设置上面的代码,就会形成C回退的时候,要么是到C->A(A不设缓存,实时刷新)->A前面的页面,要么C->B(A设缓存,不刷新就保持B)->A前面的页面,不管是那种状况都不是咱们想要的。
解决:仍是使用beforeRouteLeave,再加一层判断,当路由跳转的目标是C的时候,next设为true,如果其余跳转则设为false。
(1)判断目标路由是C的时候,保持B为true,这样C->B,
(2)当B后退的时候,判断B打开,则先关闭B,不后退,这样就能B->A
(3)A再回退的时候,B已经为false,所A就能够再返回到它的上一级。segmentfault
beforeRouteLeave(to,from,next) { /*to:目标路由 * from:当前要离开的路由 * */ if(to.name === "C"){ if(this.B){ this.B= true; next(); } else{ next();} }else { if (this.B) { this.B= false; next(false); } else { next(); } } },
这里就能够实现我要的回退顺序及效果。浏览器
说到beforeRouteLeave,就不得不跟你们提一下v-router的导航守卫,可参考官方文档。
如今我来讲下我对于组件内的守卫的一个理解。共有三个:缓存
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` } }
三者都能接收三种参数:to, from, next函数
顾名思义,
beforeRouteEnter :表示在进入当前组件前的一个操做,它执行顺序是很靠前的,而其中next的回调勾子的函数,执行则很是靠后,在mounted以后!!
咱们一般是在beforeRouteEnter中加载一些首屏用数据,待数据收到后,再调用next勾子,经过回调的参数vm将数据绑定到实例上。
所以,请注意next的勾子是很是靠后的。fetch
beforeRouteEnter(to, from, next) { next(vm => { if(to.name == '目标路由名称'){ //vm.fetchData() }else{ //vm.fetchData() } }) }
beforeRouteUpdate :表示在当前组件改变以前,这个还没用过,具体我也不太清楚里面的状况,后面用到再作介绍。
beforeRouteLeave :表示在当前组件离开以前,这个就是个人最爱了,如今对于组件的状态控制,我可都是依赖它的,像上面提到的控制弹框和跳转。this