最近在做一个 vue 移动端项目, 被缓存问题搞得头都大了, 积累了一些经验, 特此记录总结下, 权当是最近项目问题的一个回顾吧!
先描述下问题场景: A 页面 ->B 页面 ->C 页面. 假设 A 页面是列表页面, B 页面是列表详情页面, C 页面是操作改变 B 页面的一些东西, 进行提交类似的操作. A 页面进入 B 页面, 应该根据不同的列表 item 显示不一样的详情, 从 B 进入 C, 也应该根据 item 的标识比如 ID 展示不一样的内容, 在 C 页面操作后, 返回 B 页面, B 页面数据发生变化. 这个时候会有两种情况:
C 页面操作数据后返回 B 页面, B 页面对应数据应该发生变化.
C 页面直接点击左上角箭头返回, B 页面对应数据不应该发生变化. 继续返回 A 列表页面, 换一条数据, 继续进入 B 页面, B 页面展示不同内容, 进入 C 页面, C 页面刷新展示不同内容
另一种情况发生在写邮件的页面中, 添加收件人, 选人之后, 继续添加, 之前添加的联系人应该存在. 但是从写邮件页面返回邮件列表再次进入写邮件页面, 之前添加过的联系人数据就不应该存在了, 这里就涉及到如何处理缓存, 何时使用缓存, 何时清除缓存的问题了.
目前项目整体结构如下:
- <template>
- <div id="app">
- <keep-alive>
- <router-view v-if="$route.meta.keepAlive"></router-view>
- </keep-alive>
- <router-view v-if="!$route.meta.keepAlive"></router-view>
- </div>
- </template>
虽然官方提供了 include,exclude, 可以让我们决定哪些组件使用缓存, 哪些不使用缓存, 但是并没有解决我们想动态使用缓存的目的, 目前我的项目使用了如下两种方式处理缓存:
方式一 , 使用是否使用缓存标识
在路由文件 router.JS 里给每个路由添加 meta 信息, 标识是否使用缓存.
- meta: {
- isUseCache: false,// 不使用缓存
- keepAlive: true
- }
使用方式:
A->B,B 不能缓存; B->A,A 缓存.
(1)A 页面:
- beforeRouteLeave(to, from, next) {
- // 设置下一个路由的 meta
- if(to.path=='/B'){
- to.meta.isUseCache = false;
- }
- next();
- },
- activated(){
- if(!this.$route.meta.isUseCache){
- this.getData();
- }
- }
(2) B 页面
- beforeRouteLeave(to, from, next) {
- // 设置下一个路由的 meta
- if(to.path=='/A'){
- to.meta.isUseCache = true;
- }
- next();
- },
- activated(){
- if(!this.$route.meta.isUseCache){
- this.getData();
- }
- }
方式二, 强制清除缓存.
这种方式是从网上找的一种方式, 使用了 vue 内部组件之后, 不在支持动态销毁组件, 缓存一直存在, 只能从源头上下手, 清掉缓存.
- export const removeCatch = {
- beforeRouteLeave:function(to, from, next){
- if (from && from.meta.rank && to.meta.rank && from.meta.rank>to.meta.rank)
- {// 此处判断是如果返回上一层, 你可以根据自己的业务更改此处的判断逻辑, 酌情决定是否摧毁本层缓存.
- if (this.$vnode && this.$vnode.data.keepAlive)
- {
- if (this.$vnode.parent && this.$vnode.parent.componentInstance && this.$vnode.parent.componentInstance.cache)
- {
- if (this.$vnode.componentOptions)
- {
- var key = this.$vnode.key == null
- ? this.$vnode.componentOptions.Ctor.cid + (this.$vnode.componentOptions.tag ? `::${this.$vnode.componentOptions.tag}` : '')
- : this.$vnode.key;
- var cache = this.$vnode.parent.componentInstance.cache;
- var keys = this.$vnode.parent.componentInstance.keys;
- if (cache[key])
- {
- if (keys.length) {
- var index = keys.indexOf(key);
- if (index> -1) {
- keys.splice(index, 1);
- }
- }
- delete cache[key];
- }
- }
- }
- }
- this.$destroy();
- }
- next();
- }
- };
在需要清掉缓存的页面混合引入该 JS 即可.
总结
来源: https://www.jb51.net/article/149735.htm