Vuekeep-alive用法及缓存机制详解
前言在VUE项目中,有些组件或者页面不需要多次渲染,所以有些组件需要有条件地“持久化”到内存中,但是这里的持久化不是简单的数据持久化,而是整个组件(包括数据和视图)的持久化。恰好VUE提供了内置组件来实现这一点。,当包装动态组件时,缓存不活动的组件实例而不是销毁它们。与类似,是一个抽象组件:它本身不渲染DOM元素,也不出现在组件的父组件链中。当组件在中切换时,其激活和去激活的生命周期钩子函数将相应执行。基本使用有两个版本。在vue2.1.0之前,大部分是这样实现的:[JavaScript]plaintextview_copycode_?010203040506070809101112131415161718192021newRouter({routes:[{name:'a'`,`path:'/a'`,`component:A,meta:{keepAlive:true}},{name:'b'`,`path:'/b'`,`component:B}]})配置后这样路由的路由元信息,a路由的$route.meta.keepAlive为true,b路由为false。所以为true的会包裹在keep-alive中,为false的会在外层。这样路由a就达到了被缓存的效果。如果还有路由要缓存,只需要在路由元素中加上keepAlive:true即可。vue2.1.0之后keep-alive新增了两个属性:include(被包含的组件缓存生效)和exclude(被排除的组件不缓存,优先级大于include)。include和exclude属性允许有条件地缓存组件。两者都可以表示为逗号分隔的字符串、正则表达式或数组。使用正则表达式或数组时,一定要使用v-bind。简单使用:[JavaScript]plaintextview_copycode_?01020304050607080910111213141516171819202122配合router-view使用
建议使用2.1.0之后的版本作为缓存策略,代码更简洁,重复渲染少很多。Advanced进阶使用我们了解了基本的使用,但是在日常项目中并没有想象的那么简单,所以我们需要为整个项目设计一个缓存策略。如何让所有组件动态切换自己的缓存属性是一个值得考虑的问题。业务场景1、列表页进入详情页,详情页有表头和行列表。2.从详情页面的行列表进入行详情页面查看,然后返回详情页面。详细信息页面不刷新。如果修改了行详情页,我进入详情页时需要刷新。这样的业务场景在移动端非常常见。当然解决方案有很多,比如每次返回详情页时给详情页传递一个logo,然后在详情页根据logo或者最新的接口进行判断获取店铺中的数据.数据,这种判断不仅麻烦,而且无法实现页级缓存,而且很耗内存资源。如果你使用好keep-alive,你可以很容易地达到上面的效果。总体设计思路1.在store中写三个方法:setKeepAlive、setNoKeepAlive、getKeepAlive,作用是设置需要缓存的组件,清除不需要缓存的组件,获取缓存的组件。2、获取所有组件的name属性,在store中存储在一个数组中。3、App.vue挂载时获取缓存的组件数组。4.在页面路由拦截函数中,动态设置页面是否缓存。5.监听App.vue中store的变化,给include对应的数组赋值。具体实现1.在store中注册三个方法[JavaScript]纯文本view_copycode_?0102030405060708091011121314151617181920212223242526conststate={keepAliveComponents:[],}constgetters={getKeepAlive(state){returnstate.keepAlivestonestonekeepstate.(state,component){//判断keepAliveComponents中是否有之前设置的组件名,避免重复!state.keepAliveComponents.includes(component)&&state.keepAliveComponents.push(component)},setNoKeepAlive(state,component){//删除不缓存的组件constindex=state.keepAliveComponents.indexOf(component)index!==-1&&state.keepAliveComponents.splice(index,1)},}constactions={}exportdefault{state,getters,mutations,actions,}2.在路由集合中,设置要缓存的各个组件。[JavaScript]plaintextview_copycode_?123456routes.forEach((item)=>{//在路由全局钩子beforeEach中,根据keepAlive属性,统一设置页面的可缓存性//作用是每隔一段时间进入这个组件time,缓存一下store.commit(`'setKeepAlive'`,item.name)})exportdefaultroutes??注意:不是写成store.commit('setKeepAlive',item.component.name),而是item.姓名。应该写成store.commit('setKeepAlive',item.component.name),因为include接受组件的名字,但是在按需加载的情况下,打包后名字会变,所以在开始设计的时候你的项目总是尽量确保路由名称与组件名称一致。3.获取App.vue挂载时缓存的组件数组,默认全部缓存。[JavaScript]纯文本view_copycode_?01020304050607080910111213141516171819202122232425
4.动态改变页面的缓存属性。比如我想从详情页跳转到行详情,我不能让行详情在跳转前缓存起来。如果缓存了行详细信息,我每次输入都是一样的。所以我要清除缓存。">现在我需要从行明细跳转到其他关联文档,那我肯定需要把行明细缓存起来,不然再回到行明细时就什么都没有了。">5.监听缓存变化。动态设置就好了,但是现在我还是需要动态绑定include数组,所以每次页面跳转的时候都需要监听。[JavaScript]纯文本view_copycode_?010203040506070809101112131415161718192021222324252627282930