🚀 优质资源分享 🚀
学习路线指引(点击解锁) | 知识定位 | 人群定位 |
---|---|---|
🧡 Python实战微信订餐小程序 🧡 | 进阶级 | 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。 |
💛Python量化交易实战💛 | 入门级 | 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 |
- 1、通过本文可以了解到vue3 keepalive功能
- 2、通过本文可以了解到vue3 keepalive使用场景
- 3、通过本文可以学习到vue3 keepalive真实的使用过程
- 4、通过本文可以学习vue3 keepalive源码调试
- 5、通过本文可以学习到vue3 keepalive源码的精简分析
1、keepalive功能
- keepalive是vue3中的一个全局组件
- keepalive 本身不会渲染出来,也不会出现在dom节点当中,但是它会被渲染为vnode,通过vnode可以跟踪到keepalive中的cache和keys,当然也是在开发环境才可以,build打包以后没有暴露到vnode中(这个还要再确认一下)
- keepalive 最重要的功能就是缓存组件
- keepalive 通过LRU缓存淘汰策略来更新组件缓存,可以更有效的利用内存,防止内存溢出,源代码中的最大缓存数max为10,也就是10个组件之后,就开始淘汰最先被缓存的组件了
2、keepalive使用场景
- 这里先假设一个场景: A页面是首页=> B页面列表页面(需要缓存的页面)===> C 详情页
由C详情页到到B页面的时候,要返回到B的缓存页面,包括页面的基础数据和列表的滚动条位置信息
如果由B页面返回到A页面,则需要将B的缓存页清空 - 上述另外一个场景:进入页面直接缓存,然后就结束了,这个比较简单本文就不讨论了
3、在项目中的使用过程
-
keepalive组件总共有三个参数
- include:可传字符串、正则表达式、数组,名称匹配成功的组件会被缓存
- exclude:可传字符串、正则表达式、数组,名称匹配成功的组件不会被缓存
- max:可传数字,限制缓存组件的最大数量,默认为10
-
首先在App.vue根代码中添加引入keepalive组件,通过这里可以发现,我这里缓存的相当于整个页面,当然你也可以进行更细粒度的控制页面当中的某个区域组件
<router-view v-slot="{ Component }">
<keep-alive :include="keepAliveCache">
<component :is="Component" :key="$route.name" />
keep-alive>
router-view>
<script lang="ts" setup>
import { computed } from "vue";
import { useKeepAliverStore } from "@/store";
const useStore = useKeepAliverStore();
const keepAliveCache = computed(() => {
return useStore.caches;
});
script>
- 通过App.vue可以发现,通过pinia(也就是vue2中使用的vuex)保存要缓存的页面组件, 来处理include缓存,和保存页面组件中的滚动条信息数据
import { defineStore } from "pinia";
export const useKeepAliverStore = defineStore("useKeepAliverStore", {
state: () => ({
caches: [] as any,
scrollList: new Map(), // 缓存页面组件如果又滚动条的高度
}),
actions: {
add(name: string) {
this.caches.push(name);
},
remove(name: string) {
console.log(this.caches, 'this.caches')
this.caches = this.caches.filter((item: any) => item !== name);
console.log(this.caches, 'this.caches')
},
clear() {
this.caches = []
}
}
});
- 组件路由刚刚切换时,通过beforeRouteEnter将组件写入include, 此时组件生命周期还没开始。如果都已经开始执行组件生命周期了,再写入就意义了。所以这个钩子函数就不能写在setup中,要单独提出来写。当然你也可以换成路由的其他钩子函数处理beforeEach,但这里面使用的话,好像使用不了pinia,这个还需要进一步研究一下。
import { useRoute, useRouter, onBeforeRouteLeave } from "vue-router";
import { useKeepAliverStore } from "@/store";
const useStore = useKeepAliverStore()
export default {
name:"record-month",
beforeRouteEnter(to, from, next) {
next(vm => {
if(from.name === 'Home' && to.name === 'record-month') {
useStore.add(to.name)
}
});
}
}
- 组件路由离开时判断,是否要移出缓存,这个