Vue 3 组件缓存与列表优化:用 keep-alive 留住状态、用 v-memo 拦住重渲染
test12026-09-2010 次阅读
路由组件切走就丢状态?用 keep-alive 留住
列表页滚到第 20 行,点进详情再返回,默认整个组件被销毁重建,滚动位置和表单输入全没了。keep-alive 把被包裹的组件实例缓存起来,切回来时直接复用。include 精确指定要缓存的组件名,max 限制缓存数量,防止内存无限增长。
<template>
<button @click="tab = tab === 'a' ? 'b' : 'a'">切换</button>
<!-- include 精确控制哪些组件被缓存 -->
<router-view v-slot="{ Component }">
<keep-alive include="UserList,UserProfile" :max="10">
<component :is="Component" />
</keep-alive>
</router-view>
</template>
<script setup lang="ts">
import { ref } from "vue";
const tab = ref<"a" | "b">("a");
</script>
被缓存的组件必须显式命名
include 匹配的是组件的 name 选项。使用 script setup 时组件名不会自动推断,需要额外补一个普通 script 块声明 name,否则 include 不生效。
<script lang="ts">
export default { name: "UserList" };
</script>
<script setup lang="ts">
// 这里写组合式逻辑
</script>
长列表局部优化:用 v-memo 拦住无谓重渲染
keep-alive 解决“组件级”缓存,v-memo 解决“节点级”重渲染。它接收一个依赖数组,只有当数组里的某个值变化时,这一段才会重新渲染。配合大的 v-for 列表,能显著减少因父组件状态变化导致的整列重算。
<template>
<!-- 只有 id 或选中态变化时才重渲染这一项 -->
<div
v-for="item in list"
:key="item.id"
v-memo="[item.id, item.id === selectedId]"
>
<span :class="{ active: item.id === selectedId }">{{ item.name }}</span>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
const list = ref([{ id: 1, name: "A" }, { id: 2, name: "B" }]);
const selectedId = ref(1);
</script>
两者定位不同
- keep-alive:跨路由/跨 Tab 保留组件实例与状态,适合“来回切换”的页面。
- v-memo:单次渲染内对昂贵子树做精细跳过,适合“列表里只有少量项变化”的场景。
- 不要给会持续累积 DOM 的组件无脑加 keep-alive,记得用 max 兜底。
T
test1
文章作者
路由组件切走就丢状态?用 keep-alive 留住 列表页滚到第 20 行,点进详情再返回,默认整个组件被销毁重建,...
- 分类
- 技术
- 发布时间
- 2026-09-20
- 字数
- 约 1810 字
- 阅读
- 10 次
