现象:今天遇到了一个问题,我当前页搜索之后,切换到其它路由,再切回来,搜索结果还在
分析:这不是妥妥的keep-alive导致的吗,当你使用 keep-alive
并指定 include
属性后,符合条件的组件会被缓存,组件状态会被保留。
然后没有这么简单,我打开f12,发现切回来会触发onMounted,这就不对了,keep-alive切回来明明不会触发onMounted,仅在组件首次挂载到DOM时执行一次。
这就奇怪了,页面明明是keep-alive,为什么还会触发onMounted。经过deepseek询问,最有可能是
组件没有被正确缓存(include
不匹配)
<keep-alive>
的 include
是基于 组件的 name
(不是路由的 name
),如果 name
不匹配,缓存会失效。
它括号里的不是路由的name,让我明白,我应该是这里弄错了
再检查文件,确实,组件上的name没有写对,因为是后台管理系统,很多页面相似,就复制过来改,结果组件的name没有改动,导致页面根本没有被keep-alive缓存。。。
解决了这个问题,那么新的问题出来了,那我的搜索栏的数据为什么会被缓存起来
仔细分析代码
我的搜索栏数据放在js文件中,
export const searchFormData = {
searchText: "",
};
然后再vue文件中引入
<el-input v-model="formData.searchText" />
<script setup>
import { searchFormData } from './components/config'
const formData = ref(searchFormData)
</script>
然后我想到了引用类型问题,searchFormData
是一个对象,属于引用类型,当把一个对象赋值给另一个变量时,传递的是对象的引用,而非对象本身。若在代码其他地方修改了 searchFormData
对象,formData
引用的对象也会随之改变。
然后我就用了最常用的深拷贝
const formData = ref(JSON.parse(JSON.stringify(searchFormData)))
问题解决~
总结:
1.<keep-alive>
的 include
是基于 组件的 name
(不是路由的 name
),如果 name
不匹配,缓存会失效。
2.引用的对象,不能直接用,而是需要深拷贝之后才能使用,不然污染初始数据