前言
keep-alive组件的使用和原理剖析其实网上挺多的,自己也是多方观察总结了一下
0 keep-alive 原理
vue源码的地址为:keep-alive原理解析
有兴趣的小伙子可以大胆的开始读起来了,GOGOGO!
关于keep-alive的源码解析,这位字节大佬https://juejin.im/post/6844904048533979149写的挺好的,自问写不出来这种水平的分析
1 keep-alive简介
在开发中,比较常见的场景: 用户在某个列表页面选择筛选条件过滤出一份数据列表,由列表页面进入数据详情页面,再返回该列表页面,我们希望:列表页面可以保留用户的筛选(或选中)状态。
1.1 是什么?
- keep-alive是一个抽象组件:不会渲染成DOM元素,不会出现在父组件链中
- 使用keep-alive包裹动态组件时,会缓存指定条件的不活动组件实例,而不是销毁她们
1.2 做什么?
- 保存页面/组件的状态
- 避免组件反复创建和渲染,可以提升系统性能
- 用与保存组件的渲染状态,提升用户体验度
- 保持用户的登陆状态
2 keep-alive用法详解
网上教程挺多的,这里简单做一个汇总
2.1 利用meta属性
2.1.1 配置App.vue
根据不同的组件设置是否需要被缓存
//App.vue
<keep-alive>
// route的meta属性设置keepAlive为true
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
// route的meta属性不设置keepAlive时
<router-view v-if="!$route.meta.keepAlive"></router-view>
2.1.2 router中设置router的元信息meta
// router/index.js
...
routes: [
{
path: "/",
name: Home,
components: Home,
meta: {
tittle: "主页",
// 允许缓存,当把组件的keepAlive设置为false或不设置时不组件缓存
keepAlive: true
}
}
]
2.2 include、exclude
exclude优先级大于include
2.2.1 路由跳转组件
// include指需要缓存的组件名,exclude指不缓存的组件名
<keep-alive include="com1,com2,com3" exclude="nCom1,nCom2">
<component></component>
</keep-alive>
2.2.2 组件配置
// vue组件中,如com1,nCom1....
export default {
name: "com1" //组件名
data() {
return{
name: ""
}
}
}
2.3 动态判断
2.3.1 使用正则表达式判定
// 使用v-bind(因为是动态绑定:符合条件的组件缓存)
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
2.3.2 组件名动态判定
<keep-alive :include="includedComponents">
<router-view></router-view>
</keep-alive>
3 keep-alive生命周期
- 初次进入时:created > mounted > activated;退出后触发 deactivated
- 再次进入:会触发 activated;事件挂载的方法等,只执行一次的放在 mounted 中;组件每次进去执行的方法放在 activated 中
before3 keep-alive常见应用
3.1 不同页面之间跳转的缓存or不缓存
相信大家一定遇到过这种需求,从首页进入列表页面时列表页面不缓存(处于刷新状态),当添加一系列搜索条件后,再进入详情页面,然后退出来后,页面缓存(处于不刷新状态)
即: A页面 ——> B页面:刷新状态;B页面 ——> C页面 ——> B页面:缓存状态;
3.1.1 设置三个页面初始状态都为缓存
// router/index
const router = new Router({
routes: [
{
path: '/',
redirect: '/a'
},
{
// a
path: '/a',
component: A,
meta: {
keepAlive: true
}
},
{
// b
path: 'b',
component: B,
meta: {
keepAlive: true
}
},
{
// c
path: 'c',
component: C,
meta: {
keepAlive: true
}
}
]
})
3.1.2 调用beforeRouteLeave钩子函数动态设置keepAlive的值
// b跳转页面时,调用beforeRouteLeave钩子函数
beforeRouteLeave(to, from, next) {
// ...
if (to.name === "a") {
from.meta.keepAlive = false;
}
next();
},
3.1.3 缓存页面保持不在顶部时
因为router的跳转默认回到顶部,所以当有20行列表时,可能需求是缓存在你停留的那个列表位置。
b.vue
methods: {
// 获取滚动条离顶部距离
handleScrollx() {
this.top =
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop;
console.log(this.top);
},
},
// keep-alive第一次渲染时会调用此钩子函数
mounted() {
// 获取组件根元素
window.addEventListener("scroll", this.handleScrollx);
},
// 再次进入界面时的钩子函数
activated() {
// 如果滚动过
console.log("初缓存");
console.log(this.top);
if (this.top) {
document.documentElement.scrollTop = this.top;
}
window.addEventListener("scroll", this.handleScrollx);
},
//离开界面的钩子
deactivated() {
// 离开时销毁页面
window.removeEventListener("scroll", this.handleScrollx);
},
4 总结
keep-alive的用法除了保存组件的渲染状态等等,在平时的业务开发中倒是接触的蛮多的(还有大佬用来保存用户的登录状态。。。)。不过前端之路漫漫长,重要的不是弄懂一个东西怎么用,而是去弄懂它的原理,学习它的思想从而将其内化为自己知识库,我想这也是开源的魅力吧。。。