vue3 keep-alive组件缓存
一 keepalive的特点
keepalive是vue3中的一个全局组件
keepalive 本身不会渲染出来,也不会出现在dom节点当中,但是它会被渲染为vnode,通过vnode可以跟踪到keepalive中的cache和keys,当然也是在开发环境才可以
二 keep-alive的功能
1 keepalive 最重要的功能就是缓存组件
keepalive 通过LRU缓存淘汰策略来更新组件缓存,可以更有效的利用内存,防止内存溢出,源代码中的最大缓存数max为10,也就是10个组件之后,就开始淘汰最先被缓存的组件了
三 keep-alive的生命周期
1 未添加keepAlive的生命周期
beforeCreate
=>created
=>beforeMount
=>mounted
=>beforeUpdate
=>updated
=>beforeUnmount
=>unmounted
2 添加keepAlive的生命周期
activated
:当keepalive
包含的组件渲染的时候触发
deactived
:当keepalive
包含的组件销毁的时候触发
keep-alive
的生命周期
activated
: 页面第一次进入的时候,钩子触发的顺序是created->mounted->activated
deactivated
: 页面退出的时候会触发deactivated
当再次前进或者后退的时候只触发activated
四 keepAlive的使用
1 在App.vue中使用keep-alive标签,表示缓存所有页面
<div id="app"><keep-alive><tar-bar></tar-bar><div class="container"><left-menu></left-menu><Main /></div></keep-alive>
</div>
2 按条件缓存,使用include,exclude判断是否缓存
// 1. 将缓存 name 为 cc 的组件,如果有多个,可用逗号分<keep-alive include='cc,cc1,cc2'><router-view/></keep-alive>// 2. 将不缓存 name 为 cc 的组件<keep-alive exclude='cc'><router-view/></keep-alive>// 3. 还可使用属性绑定动态判断<keep-alive :include='includedComs'><router-view/></keep-alive>
3 在router目录下的index.js中
//第一步:使用meta:{keepAlive = true },表示需要缓存
const routes = [{path:'/',component:Home,meta:{keepalive:true}},{path:'/login',component:Login},{path:'/edit',component:Edit,meta:{istoken: true}},{path:'/home',component:Home,meta:{keepalive:true}}
]//第二步:在App.vue中进行判断
<div id="app"><!--keep-alive 表示页面不会被销毁,即保持页面状态--><keep-alive><router-view v-if="$route.meta.keepalive"></router-view></keep-alive><router-view v-if="!$route.meta.keepalive"></router-view></div>
4 条件缓存(通过插槽的方式)
列表页面跳转到详情页面的情况,保证上一级页面的页面数据不会刷新,例如两个页面A页面—>>>列表页,B页面—>>>详情页,A–>>B–>>A ,缓存A页面的数据
<template><router-view v-slot="{ Component }"><keep-alive :include="includeList"><component :is="Component"/></keep-alive></router-view>
</template><script>
import { reactive, watch, toRefs } from '@vue/runtime-core'
import { useRoute, useRouter }export default {name: 'Test',setup(){const state = reactive({includeList: []})const route = useRoute()// const router = useRouter()watch(() => route,(newVal,oldVal)=>{if(newVal.meta.keepAlive && state.includeList.indexOf(newVal.name) === -1){state.includeList.push(newVal.name);console.log(state.includeList);}},{deep:true}) // 开启深度监听return{...toRefs(state)}}}
</script>
5 路由页面的配置
{path: 'test',name: 'Test',component: () => import('@/views/Test'),meta: {keepAlive: true, // 组件需要缓存}
}
参考文章: 传送门