用vue.js做单页应用的时候,我们可能会需要类似app页面跳转的形式:前进刷新页面,后退缓存页面。我们知道可以通过keep-alive标签来缓存一个页面,如果我们直接用keep-alive套在<router-view>上会导致所有的页面都被缓存,这可能不是你想要的,因此,我们一般的写法如下:

这样通过在meta中设置哪些是需要保留的,哪些是不需要保留的,即可做到缓存想要的页面。

不过这样设置的页面还是有问题,就是被缓存的页面会一直被缓存,无论别人是前进来到这个页面还是别人后退来到这个页面都会缓存,无法做到前进刷新,后退缓存的效果。

在网上搜索vue.js前进刷新,后退缓存,我们会发现很多人说利用beforeRouteLeave如下配置即可:

就是在要发生前进刷新,后退缓存的页面的里面检测页面离开的时候,如果是向后走,就保持keep_alive为true(keep_alive默认为true),这样返回的时候页面是被缓存的;如果是向前走,keep_alive为false,那么前进的时候就不会保留。看样子好像没什么问题,可仔细一想就会发现问题,为此,做了一个小demo,说明问题出在哪。

上面就是一个需要用到前进刷新,后退缓存页面的实际场景,页面结构大致如下:

background Layer 1 A:主页 B:填写申请页面 C:填写手机绑定 D:成功页面 A B D 进入 绑定了手机号 没绑定手机号 C 绑定成功,返回

我们注意上面的B页面,因为B页面需要先跳转到C页面绑定手机号,绑定回来之后,我们要恢复B页面填写的数据,因为如果不恢复的话,用户需要再次填写B页面的数据,就不太友好了。

上面的demo就是利用beforeRouteLeave来实现的,我们可以发现确实做到了部分的前进刷新,后退缓存:

1.从A->B,B页面填写完内容后回退到A,再从A->B,我们发现B没有内容了,说明前进刷新可以。

2.从A->B,B页面填写完内容后进入C,C回退到B,B的页面数据还在,说明后退缓存可以。

不过为什么说这个是不完善的前进刷新,后退缓存呢?我们来看看下面的操作就知道了:

从A->B,B中填写内容如下:

然后回退到A,这个时候keep-alive变成false了,再次进入B,这个时候应该是没有内容的,我们在B填入以下内容:

再进入C,这个时候keep-alive为true,回退有缓存,填写完之后跳转到B,我们可以发现这个时候B页面是如下样子:

发现问题没有,就是这个时候的B缓存的页面不是我们刚从填写的lisi,而是我们第一次缓存填写的zhangsan。

问题原因很简单,就是第二次填写B页面的时候,B页面是在离开的时候keep-alive才变成true,这个时候是不会缓存第二次填写的内容的,当C->B时,拿的其实时第一次的缓存,而不是第二次的。

正确操作

我们现在看看正确的前进刷新,后退缓存的demo:

这里没有设置B页面的keep_alive,因为keep_alive即使变了,vue.js不会马上保存该页面,总会有一个延迟,因此,这里就将有缓存的页面keep_alive一直设置为true。和上面相反,这里关注的时前面来的路径,用beforeRouteEnter监听,如果是来自前面的,我们就将所有的数据reset,恢复成开始的样子,关键代码如下:

流程大致如下:

background Layer 1 第一次进入 不是第一次进入 activated 首次进没有动作 mounted activated 非首次需要先reset,再fetchData reset fetchData (事件) (事件) (事件) (方法) (方法) reset方法把data全部重置 fetchData表示进入页面后的动作,例如通过ajax获取一些数据。 B页面 前面页面进入

其他文章

0
我要评论

评论

返回
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

提交
还可以输入500个字