keep-alive
是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。
使用方法:
结合路由属性
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
通过设置route中meta的keepAlive属性来决定是否添加keep-alive的标签,也可以自定义标签(看个人喜好)
动态匹配路由
- include: 属性用于指定应该被缓存的组件名称。这个属性接受一个字符串或字符串数组,其中每个字符串都是组件的
name
属性。当组件的name
与include
数组中的任何一个字符串匹配时,该组件就会被缓存。 - exclude: 字符串或正则表达式。
- max:用于指定缓存组件的最大数量。当您使用
<keep-alive>
来缓存多个组件时,这个属性允许您限制缓存的组件数量,从而防止内存占用过多。
<keep-alive :include="keepAliveNameList" :max="keepAliveMaxNum">
<component :is="Component" :key="$route.meta.routerKey" ref="componentRef" />
</keep-alive>
🔥 组件的name属性与include包含的数组的名字一定要相同(大小写也要一致),因为我是动态添加的路由,忽略了页面的name属性,导致就算keepAliveList添加了组件name还是无法实现
export default defineComponent({
name: 'caseReportManage',
components: {Input},
setup() {.......
这里的name一定要写对
使用 <keep-alive>
来缓存组件时,key
属性是必须的,因为它告诉 Vue 如何处理缓存组件的激活和卸载。当组件被重新渲染时,Vue 会使用 key
属性来确定是否应该复用之前的组件实例,还是创建一个新的实例。
如果 key
属性在两次渲染中保持一致,Vue 将会尝试复用之前的组件实例,从而避免不必要的重新创建。如果 key
属性发生了变化,Vue 会认为这是两个不同的组件,因此会创建一个新的组件实例。
代码中,在将 $route.meta.routerKey
作为 key
的值。这意味着每当路由发生变化时,routerKey
也会发生变化,从而导致组件被重新创建,因为 key
属性发生了变化。
如何解决keep-alive缓存一直存在的问题,比如关掉了页面重新开启,缓存还是存在
❓ 动态生成 routerKey
,您可以确保每次路由变化时,routerKey
的值都会有所不同,从而迫使 <keep-alive>
组件创建一个新的组件实例,并刷新缓存。
这种方法的关键在于确保 routerKey
的值能够反映当前路由的状态,这样 <keep-alive>
就可以根据这个键来决定是否缓存组件。通过结合时间戳和路由的标题,您可以创建一个几乎总是唯一的键,这有助于避免缓存过期的组件。
// 获取当前时间戳
const timestamp = Date.now();
// 获取路由的 meta.title
const title = route.meta.title || 'default-title';
// 生成 routerKey
route.meta.routerKey = `${timestamp}-${title}`;
但是如果 routerKey
总是变化,那么 <keep-alive>
将始终创建新的组件实例,这可能会导致不必要的性能开销。
因为设置了 <keep-alive>
的 max
属性,那么即使 routerKey
总是变化,<keep-alive>
组件也会根据 max
属性来限制缓存组件的数量。当缓存的组件数量达到 max
的限制时,最久未被访问的组件将被移除,为新组件腾出空间。
清除keep-alive遇到的坑
⚠️ 在 Vue 3 中,<keep-alive>
组件的内部缓存机制是不公开的,这意味着不能直接访问或操作 <keep-alive>
的缓存。这是因为在 Vue 3 中,<keep-alive>
组件的设计是为了简化组件缓存的复杂性,同时保持性能和灵活性。
在 Vue 2 中,<keep-alive>
组件暴露了一些内部属性和方法,允许直接访问和管理缓存。但是在 Vue 3 中,这种直接访问缓存的方式被去掉了,以避免直接操作缓存可能带来的复杂性和潜在的问题。
⚠️ 将一个组件从 <keep-alive>
的 include
列表中移除(即 exclude
),然后再重新包含它(即 include
),之前缓存的数据通常仍然会保持不变。这是因为 <keep-alive>
内部维护了一个组件的缓存,这个缓存是基于组件的实例和它的 key
来管理的。
还在学习中……