一、问题描述
在某些情况下,vue项目前端有些情况下需要设置路由跳转,页面不刷新,比如:
前进导航刷新页面,后退不刷新,page1–>page2–>page3,每次前进到一个新页面都需要获取数据,而按下后退键后,不再获取新数据,而是使用之前缓存的数据;
Tab也之间切换,某些页面不需要刷新,因为刷新页面会重置用户的过滤条件,对用户体验十分不友好;
二、什么是keep-alive
keep-alive顾名思义,保持活跃。保持谁活跃呢?
首先我们知道,因为vue就是组件化编程,一个.vue文件就是一个组件。就像万事万物一样,都有从出生到消亡的生命周期过程,vue的组件也是一样,也有自己的生命周期,比如create创建组件、mounted往组件上挂数据、update更新组件上挂的数据,destroy把组件实例销毁。
所以使用keep-alive就是保持组件活跃,不会被destroy销毁掉,就一直还活着,组件没有被销毁掉的话,组件上挂载的数据就还存在,所以状态就可以保留,所以,keep-alive就可以保持组件的状态。
三、keep-alive属性
include 值为字符串或者正则表达式,匹配的组件会被缓存。
exclude 值为字符串或正则表达式,匹配的组件不会被缓存。
四、生命周期
当组件在 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。
- activated
在 keep-alive 组件激活时调用
使用 keep-alive 会将数据保留在内存中,如果要在每次进入页面的时候获取最新的数据,需要在 activated 阶段获取数据,承担原来 created 钩子函数中获取数据的任务
2.deactivated
注意: 只有组件被 keep-alive 包裹时,这两个生命周期函数才会被调用,如果作为正常组件使用,是不会被调用的,以及在 2.1.0 版本之后,使用 exclude 排除之后,就算被包裹在 keep-alive 中,这两个钩子函数依然不会被调用!另外,在服务端渲染时,此钩子函数也不会被调用
五、keep-alive的用法
5.1、include/exclude用法
// include 只缓存组件名字为home的组件,其他组件不会缓存,而exclude恰好相反
<keep-alive include="home">
<router-view />
</keep-alive>
5.2、keep-alive结合路由中的meta属性来控制组件缓存
5.2.1 根据需要设置路由是否需要缓存
{
path: '/',
name: 'home',
meta: {
keepAlive:true
},
component: Home
}
5.2.2 router-view中判断时候需要keep-alive缓存控制
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
六、产生问题
组件被缓存,当关闭菜单(路由)并没有被销毁,所以组件在切换的时候也就不会被重新创建,也就不会调用created等生命周期函数
解决方法
使用activated与deactivated来获取当前组件是否处于活动状态我在home组件里面写入了activated与deactivated生命周期函数
activated:组件激活时调用
activated(){
// 进入home组件就会打印
console.log(“路由被激活,初始化路由”)
}
deactivated:组件停用时调用
deactivated(){
// 关闭home组件就会打印
console.log(“路由被销毁,销毁路由”)
}
七、钩子函数的执行顺序
不使用keep-alive
beforeRouteEnter --> created --> mounted --> destroyed;
使用keep-alive
beforeRouteEnter --> created --> mounted --> activated --> deactivated;
再次进入缓存的页面,只会触发beforeRouteEnter -->activated --> deactivated ,created和mounted不会再执行;