Logo

Vue3 keep-alive 缓存机制让页面切换更流畅

author
YGHub·2024-11-21·2·字数:353 字·阅读时间:2 分钟

在日常开发中,我们经常遇到这样的场景:用户在列表页筛选数据后进入详情页,返回时希望保持筛选条件和分页状态。如何用 Vue3 的 keep-alive 来优雅地解决这个问题?

一、keep-alive 基础用法

1. 基本语法:

vue
<template>
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
</template>
 

2.配置缓存规则:

vue
<template>
<router-view v-slot="{ Component }">
<keep-alive
:include="['UserList', 'ProductList']" // 需要缓存的组件名
:exclude="['Login']" // 不需要缓存的组件名
:max="10" // 最大缓存数量
>
<component :is="Component" />
</keep-alive>
</router-view>
</template>
 

二、实战案例:商品列表与详情页

1.商品列表页面:

vue
// ProductList.vue
<template>
<div>
<!-- 搜索条件 -->
<div class="search-form">
<a-input v-model:value="searchForm.keyword" placeholder="搜索关键词" />
<a-select v-model:value="searchForm.category" style="width: 200px">
<a-select-option value="1">分类一</a-select-option>
<a-select-option value="2">分类二</a-select-option>
</a-select>
<a-button type="primary" @click="handleSearch">搜索</a-button>
</div>
 
<!-- 商品列表 -->
<a-table
:columns="columns"
:data-source="productList"
:pagination="pagination"
@change="handleTableChange"
/>
</div>
</template>
 
<script setup lang="ts">
import { reactive, ref, onActivated } from 'vue'
 
// 必须设置组件名称,供 keep-alive 识别
defineOptions({
name: 'ProductList'
})
 
// 搜索条件
const searchForm = reactive({
keyword: '',
category: undefined
})
 
// 分页配置
const pagination = reactive({
current: 1,
pageSize: 10,
total: 0
})
 
// 表格数据
const productList = ref([])
 
// 获取数据
const fetchData = async () => {
// 实际开发中这里调用接口
// const res = await api.getProductList({
// ...searchForm,
// page: pagination.current,
// pageSize: pagination.pageSize
// })
}
 
// 搜索
const handleSearch = () => {
pagination.current = 1
fetchData()
}
 
// 表格翻页
const handleTableChange = (pag) => {
pagination.current = pag.current
fetchData()
}
 
// 组件被激活时触发
onActivated(() => {
console.log('ProductList 组件被激活')
})
</script>
 

2.商品详情页面:

vue
// ProductDetail.vue
<template>
<div>
<a-button @click="goBack">返回列表</a-button>
<div class="product-info">
<!-- 商品详情内容 -->
</div>
</div>
</template>
 
<script setup lang="ts">
import { useRouter } from 'vue-router'
 
const router = useRouter()
 
const goBack = () => {
router.back()
}
</script>
 

3. 路由配置:

ts
import { createRouter, createWebHistory } from 'vue-router'
 
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/products',
name: 'ProductList',
component: () => import('../pages/ProductList.vue'),
meta: {
keepAlive: true // 标记需要缓存
}
},
{
path: '/product/:id',
name: 'ProductDetail',
component: () => import('../pages/ProductDetail.vue'),
meta: {
keepAlive: false // 不需要缓存
}
}
]
})
 
export default router
 

4. App.vue 中根据路由 meta 配置缓存:

vue
// App.vue
<template>
<router-view v-slot="{ Component, route }">
<keep-alive>
<component
:is="Component"
v-if="route.meta.keepAlive"
/>
</keep-alive>
<component
:is="Component"
v-if="!route.meta.keepAlive"
/>
</router-view>
</template>
 

三、注意事项

1.组件必须设置 name 属性,keep-alive 根据 name 进行缓存

2.被缓存的组件不会触发 onMounted,而是触发 onActivated

3.合理设置 max 属性,避免缓存过多导致内存占用过大

4.配合 vue-router 的 meta 属性可以更灵活地控制缓存

5.如果缓存的组件依赖路由参数,需要在 onActivated 中处理

总结

keep-alive 是 Vue 中非常实用的性能优化工具,合理使用可以大大提升用户体验。在实际开发中,建议:

1.列表页面使用 keep-alive 缓存

2.详情页面一般不缓存

3.注意内存占用,适时清理缓存

Preview

2

点个赞 ~

版权申明: © 本文著作权归YGHub所有,未经YGHub网授权许可,禁止第三方以任何形式转载和使用本文内容。