什么场景下需要做组件缓存?
当我们实现一个列表页面,点击其他栏目之后,再返回列表页面的时候,我们希望回到离开之前的列表页面,并且回来的时候,滚动条的位置,分页信息,频道信息都是我们离开之前样子,这种情况下我们就需要做页面的缓存
滚动条缓存页面: 缓存前记录滚动条的位置,只缓存滚动条处于的页面,防止整页面都缓存
解决方法:监听滚动条的位置,并且做持久化,在activated恢复滚动条的位置
代码如下:
mounted(){
//监听滚动条的滚动,保存滚动条的位置
this .$refs .1istRef .onscro11 = function (e){
1oca1storage .setitem('scro11Top', e.target .scro11Top)
}
},
//变为激活状态
activated() {
// 给.articTe-1ist元素赋值滚动条的位置数据
this.$refs.listRef.scrol1Top = localstorage .getItem('scro1Top')
}
方法一:vue的内置组件keep-alive
先要知道keep-alive的属性:
include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max - 数字。最多可以缓存多少组件实例。
keep-alive是用来做状态数据缓存的,所以有遵循的缓存策略
LRU (least recently used)缓存策略
LRU 缓存策略∶ 从内存中找出最久未使用的数据并置换新的数据。
最常见的实现是使用一个链表保存缓存数据,详细算法实现如下∶
· 新数据插入到链表头部
· 缓存数据被访问,则将数据移到链表头部
· 链表满的时候,将链表尾部的数据丢弃。
用vue的内置组件keep-alive,来实现页面缓存控制。
主要作用:保留组件状态或避免重新渲染。
当组件在 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。
在未使用keep-alive组件时,在页面回退时会重新渲染页面,触发created钩子,使用体验不好
用法:将需要缓存的页面用包裹起来
keep-alive两种按需缓存的两种:
1. 通过if判断是否将放在keep-alive中进行缓存
<!-- 使用keep-alive缓存页面 -->
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<!-- 不需要缓存的页面放这里 -->
<router-view v-if="!$route.meta.keepAlive"></router-view>
// 路由配置
routes: [
{
// 需要缓存的路由,添加原信息
keepAlive {
path: '',
component: Home,
meta: { keepAlive: true }
},
}
]
2.通过给keep-alive设置include属性控制哪些页面要做缓存
用include属性,必须给页面设置name属性,写好名称,不然找不到
<!-- 使用keep-alive缓存页面,通过include缓存部分页面 -->
<keep-alive :include="cachedViews">
<router-view></router-view>
</keep-alive>
data() {
return {
// 指定要缓存的组件name数组
cachedViews: ['Layout']
}
}
方法二:将状态存储在LocalStorage / SessionStorage
只需要在组件即将被销毁的生命周期中在 LocalStorage / SessionStorage 中把当前组件的 state 通过 JSON.stringify() 储存下来就可以了。在这里面需要注意的是组件更新状态的时机。
缺点:
- 状态通过 JSON 方法储存(相当于深拷贝),如果状态中有特殊情况(比如 Date 对象、Regexp 对象等)的时候会得到字符串而不是原来的值。(具体参考用 JSON 深拷贝的缺点)
- 组件被销毁,切换回来的时候会重新渲染
方法三:单页面渲染
要切换的组件作为子组件全屏渲染,父组件中正常储存页面状态。
优点: 代码量少,不需要考虑状态传递过程中的错误