概念
keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 transition 相似,keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件链中。
作用
在组件切换过程中将状态保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性。
<!-- 失活的组件将会被缓存!-->
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
当组件在 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行
- activated:如果使用keep-alive缓存,每次进入页面时需要执行的代码可以放在这里
Props
- include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
- exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
- max - 数字。最多可以缓存多少组件实例。
- 最多可以缓存多少组件实例。一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。
<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>
<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
<component :is="view"></component>
</keep-alive>
<keep-alive :max="10">
<component :is="view"></component>
</keep-alive>
使用
切换当前路由时,内容会被缓存,页面将保留之前的操作状态
<keep-alive>
<router-view></router-view>
</keep-alive>
window.sessionStorage.setItem('fydz/sub/list', true);
注意
- 问题
- 在多层级使用时,如三级页面,前两个层级需要缓存,多次在层级上转换时会有问题
- 问题详述
- 在第一次进入第一、二层级后,点击从三级回到二级或从二级回到三级,页面会保持原状,但再次点进一、二级后,页面内容不会更新
- 修改bug需要刷新页面
- 点击进入页面而不是返回,却不更新是bug,因此需要在进入页面时刷新页面(或初始化、更新页面数据)
- 修改方案
- 错误做法:在进入页面时传参,如第一层设置this.$route.query.isFresh = true,在第二层级的activated里面判断是否刷新,此时第三层级点击返回后,由于第二层级的query上带有isFresh=true,且子层级改不了,页面会一直刷新
- 正确方案:使用sessionstorage作为是否刷新的判断
- 第一层级
window.sessionStorage.setItem('fydz/sub/list', true);
- 第二层在activated中
if (window.sessionStorage.getItem('fydz/sub/list') && window.sessionStorage.getItem('fydz/sub/list') === 'true') {
this.init();
}
- 第三层中的返回方法写
if (window.sessionStorage.getItem('fydz/sub/list')) {
window.sessionStorage.setItem('fydz/sub/list', false);
}
// 或者
if (window.sessionStorage.getItem('fydz/sub/list')) {
window.sessionStorage.removeItem('fydz/sub/list');
}
- 注意要在第二层中写removeItem删除sessionStorage
beforeDestroy() {
if (window.sessionStorage.getItem('fydz/sub/list')) {
window.sessionStorage.removeItem('fydz/sub/list');
}
}
ps:this.init()里面需要包括初始化传参、初始化data,初始化请求等各种操作;同时需要添加一个flag:freshPage,刷新vue页面(:key="freshPage")