当前位置:网站首页> 详解Vue适时清理keepalive缓存方案
详解Vue适时清理keepalive缓存方案
2022-07-05 14:16:00 【1024问】
需求
思考
尝试
1. 手动操作 keep-alive 组件的 cache 数组
2. exclude 大法好
Demo
需求单页面应用中,用户进入表单填写页面,需要初始化表单内容,填写过程中可能涉及到地图选点或者列表选择等操作,需要到新的页面选择并回调显示。
此时我们需要缓存表单填写页面实例,当退出表单填写或提交完表单内容之后,需要销毁当前表单实例,下次进入重新进行初始化
思考说到 Vue
缓存,我们肯定首先选择官方提供的缓存方案 keep-alive
内置组件来实现。
keep-alive
组件提供给我们缓存组件的能力,可以完整的保存当前组件的状态,这帮了我们很大的忙
但实际业务场景中,我们很多时候是按需缓存页面的,就像 App
开发那样,每个页面都是单独的一个页面实例,由于 Vue Router
的限制,每个页面有固定的一个 path
,所以导致每次访问这个 path
都会命中同一个组件实例
这个时候可能会有小伙伴说
诶,不是可以用
activated
来进行页面更新或者处理吗?
没错,是可以这样,但是,有些操作是 mounted
里面要做,有些需要放到 activated
里面更新,代码要处理很多进入页面的操作,就很麻烦啊。
此时就有两个思考方向:
在必要的时候清除掉缓存页面的实例
每次 push 页面的时候,保证当前页面是全新的实例对象,和 App
页面栈相同
第二种方案可以比较物理的解决需求中的问题,但是需要改动的地方很多,比如 Vue Router
中路由切换的时候,是否采用动态生成 path
,确保当前页面实例不唯一,而且我们也要做好自己的页面栈管理,类似于 iOS
中的 UINavigationController
,以便于及时清理栈中缓存的页面实例
因为改动比较大,而且需要大量测试,所以最后还是选择在方案一的方向进行探索和尝试。
尝试1. 手动操作 keep-alive 组件的 cache 数组// Vue 2 keep-alive 部分源码片段const { cache, keys } = this;const key: ?string = vnode.key == null ? // same constructor may get registered as different local components // so cid alone is not enough (#3269) componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : "") : vnode.key;if (cache[key]) { vnode.componentInstance = cache[key].componentInstance; // make current key freshest remove(keys, key); keys.push(key);} else { // delay setting the cache until update this.vnodeToCache = vnode; this.keyToCache = key;}
通过路由守卫在特定的情况下删除 cache
数组中的页面实例,同时 destory
当前实例
removeKeepAliveCacheForVueInstance(vueInstance) { let key = vueInstance.$vnode.key ?? vueInstance.$vnode.componentOptions.Ctor.cid + (vueInstance.$vnode.componentOptions.tag ? `::${vueInstance.$vnode.componentOptions.tag}` : ""); let cache = vueInstance.$vnode.parent.componentInstance.cache; let keys = vueInstance.$vnode.parent.componentInstance.keys; if (cache[key]) { vueInstance.$destroy(); delete cache[key]; let index = keys.indexOf(key); if (index > -1) { keys.splice(index, 1); } }}
这种方案比较繁琐,但由于是直接操作 cache
数组,可能会产生一些预期外的泄漏问题或者运行问题,虽然我自己尝试的时候没有发现。。
在 Vue 3
中我也尝试去寻找对应的 cache
数组,还真被我找到了,但是 Vue 3
源码中对于 cache
数组的操作权限仅限于开发环境
// Vue 3 KeepAlive 组件片段if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) { ;(instance as any).__v_cache = cache}
部署生产环境之后就没办法通过 instance.__v_cache
来获取 cache
数组了,所以这种方案到 Vue 3 就没办法进行下去啦。
于是乎,就有了第二个尝试
2. exclude 大法好之前接触 keep-alive
所有注意力都放在 include
这个属性上面,其实 exclude
属性同样重要,而且效果和我们直接删除 cache
数组异曲同工。
// Vue 3 KeepAlive 组件片段 if ( (include && (!name || !matches(include, name))) || (exclude && name && matches(exclude, name)) ) { current = vnode return rawVNode }
如果 exclude
里面有值,那么就返回当前新的实例不从 cache
里面获取。而且 exclude
的优先级是高于 include
的。
利用这一点,我们就可以通过操作 exclude
中的内容,来达到控制缓存页面的效果。
而且 exclude
在 Vue 3
中的控制更为方便,只需要定义一个全局的 exclude
响应式变量就可以随处操作了,清除的具体方式取决于业务流程
export const excludes = ref<string[]>([]);// 需要删除的时候export function removeKeepAliveCache(name: string) { excludes.value.push(name);}// 需要恢复缓存的时候export function resetKeepAliveCache(name: string) { excludes.value = excludes.value.filter((item) => item !== name);}
Demo这里提供一个小 demo 演示一下缓存清除效果:
https://ztstory.github.io/vue-composition-demo/#/
流程:
Index
与 Input
为缓存页面 Input
返回到 Index
时清除 Input
缓存,重新进入 Input
页面激活缓存 Demo 源码地址:https://github.com/ZTStory/vue-composition-demo
到此这篇关于详解Vue适时清理keepalive缓存方案的文章就介绍到这了,更多相关Vue清理keepalive缓存内容请搜索软件开发网以前的文章或继续浏览下面的相关文章希望大家以后多多支持软件开发网!
边栏推荐
- 如何深入理解“有限状态机”的设计思想?
- 一网打尽异步神器CompletableFuture
- R语言dplyr包select函数、group_by函数、mutate函数、cumsum函数计算dataframe分组数据中指定数值变量的累加值、并生成累加数据列
- 总量分析 核算方法和势方法 - 分摊分析
- How can non-technical departments participate in Devops?
- Principle and performance analysis of lepton lossless compression
- R language uses the multinom function of NNET package to build an unordered multi classification logistic regression model, and uses the coef function to obtain the log odds ratio corresponding to eac
- 基于伯努利原理的速度监测芯片可用于天然气管道泄露检测
- Mysql database installation tutorial under Linux
- Enjoy what you want. Zhichuang future
猜你喜欢
How to introduce devsecops into enterprises?
神经网络物联网未来发展趋势怎么样
乌卡时代下,企业供应链管理体系的应对策略
ASP. Net large takeout ordering system source code (PC version + mobile version + merchant version)
Introduction, installation, introduction and detailed introduction to postman!
如何深入理解“有限状态机”的设计思想?
Current situation, trend and view of neural network Internet of things in the future
SAS接口有什么优势特点
【学习笔记】阶段测试1
区间 - 左闭右开
随机推荐
ASP. Net large takeout ordering system source code (PC version + mobile version + merchant version)
Guofu hydrogen energy rushes to the scientific and Technological Innovation Board: it plans to raise 2billion yuan, and 360million yuan of accounts receivable exceed the revenue
区间 - 左闭右开
Thymeleaf th:with use of local variables
How to call the function mode of one hand and one machine
mysql 自定义函数 身份证号转年龄(支持15/18位身份证)
Thymeleaf 常用函数
LeetCode_ 3 (longest substring without repeated characters)
Why do mechanical engineers I know complain about low wages?
R语言ggplot2可视化:可视化折线图、使用theme函数中的legend.position参数自定义图例的位置
POI set the data format of the column (valid)
Some ideas about Apache mesos
The forked VM terminated without saying properly goodbye
MySQL user-defined function ID number to age (supports 15 / 18 digit ID card)
R language ggplot2 visual density map: Visual density map by group and custom configuration geom_ The alpha parameter in the density function sets the image transparency (to prevent multiple density c
用“新”字来吸引好奇的人群
R language ggplot2 visualization: use ggplot2 to visualize the scatter diagram, and use the labs parameter to customize the X axis label text (customize X axis labels)
Qingda KeYue rushes to the science and Innovation Board: the annual revenue is 200million, and it is proposed to raise 750million
Use the word "new" to attract curious people
openGauss数据库源码解析系列文章—— 密态等值查询技术详解(下)