【vue进阶之旅】如何使用keep-alive做组件缓存?

语言: CN / TW / HK

前言

大家好,我是东东吖,一名前端工程师。今天我要给大家分享的是如何使用keep-alive做组件缓存?

为什么要做组件缓存?什么场景下会用到组件缓存?或许很多小伙伴根本不知道keep-alive这个组件,也或许知道keep-alive可以做组件缓存,但是却从来没有实践过,懵懵懂懂,刚好我曾经有过使用keep-alive做组件缓存相关的项目经验,现在我就给大家分享一下keep-alive这个组件到底是怎么回事?在项目中应该怎么用?应该注意些什么?

keep-alive的使用场景?

现在给大家讲一讲keep-alive的使用场景,比如你在购物网站,不断地滚动屏幕,当滚动到了很久很久,你突然发现一件你很喜欢的商品,你点击进入详情,当你查看了该商品的详情,返回出来要保持之前的位置继续往下浏览商品,你会怎么做?再比如你在一个页面有多个tab,默认是会选中第一个tab,当你在第二个tab切换到其他页面的时候(比如对应tab的详情),再次返回到当前的页面,要保持你去之前的tab和对应的状态,你会怎么做?

这里如果没有使用组件缓存的话,当你点击商品详情页面,当前商品列表的页面就会销毁,当你从商品详情返回到商品列表的时候,这个页面已经重新进行了构建,是不会保存在你之前刚刚浏览的位置的,又会返回到最顶上的位置,这个时候你让用户再重复把刚刚的内容再刷一遍吗?而用户的需求是继续之前的位置,可以接着往下滑。切换tab的场景也是这样的道理,不会保存你离开之前的状态,下面我会深入讲解。

vue的八大生命周期

我目前写了一个tab案例,帮助大家理解keep-alive,对应的逻辑和代码如下: 一共有tab1和tab2两个页面,点击按钮会显示对应tab的内容,点击color按钮,会变更内容的颜色,同时会在控制台打印所有生命周期。

```

```

当我们进入页面,当前页面的组件会被创建,并会显示tab的内容,触发从构建待到挂载相关的生命周期。 ``` beforeCreate........ created.....组件创建了 beforeMount........ mounted........

```

image.png

当我们点击tab2按钮会切换到tab2的内容,页面发生改变,会触发组件更新相关的生命周期 beforeUpdate........ updated........

image.png

当我们点击color按钮,会给tab2的内容变跟一个颜色,页面发生改变,还是会触发组件更新相关的生命周期 beforeUpdate........ updated........

image.png

当我们点击其他页面,当前页面进会进行销毁,会触发组件销毁相关的的生命周期: beforeDestroy.... index.vue?6ced:62 destroyed.....组件销毁了

image.png

如何利用keep-alive做组件缓存?

现在问题来了,当我们再次进入刚才的页面,页面优化重新进行构建,并且会默认显示tab1的内容,文字的颜色也是默认黑色。

image.png

如果我们现在重新切换到刚刚的页面,想要默认显示tab2的内容,并且颜色是经过变更的,也就是想要返回之后,保存我们切走前的状态,该怎么办呢?

那就需要用到我们的keep-alive组件缓存,我们keep-alive组件是vue的官方组件无需注册,直接使用,当我们直接把keep-alive的组件包裹 ,就能到达我们的效果,我们把他加上再试一下。

image.png

我们发现keep-alive维持了我们离开当前页面的效果,同时控制台的生命周期也有了一些变化,那是怎么回事呢?

使用keep-alive之后,vue生命周期有何变化?

当我们使用keep-alive之后,我们首次进入该页面

image.png 我们会发现会多一个生命周期activated,这个生命周期代表组件被激活了。 beforeCreate........ created.....组件创建了 beforeMount........ mounted........ activated........组件激活了

image.png

当我们离开当前页面,会触发另外一个生命周期deactivated,这个生命周期代表组件失活了,并且你会发现,当我们离开当前页面,并不会触发组件销毁的生命周期,也就说明当前组件并没有被销毁,而是被缓存起来了,这也是我们为啥能实现我们想要效果的原因。

image.png

当我们反复切换其他页面和当前页面,从第二次进入当前页面会触发activated,离开当前页面会触发deactivated,并不会再去触发beforeCreate、created、beforeMount、mounted这四个生命周期,所以我们做项目使用keep-alive做组件缓存的时候,调用的接口应该是在组件被激活时的生命周期activated去掉,而不是在created生命周期去掉,因为created只会执行一次。

keep-alive 的属性配置

keep-alive会缓存被包裹的组件,当我们包裹在 就说明整个项目的路由都被缓存了,如果我们想要只缓存部分页面,该怎么办呢?

``` 在keep-alive上有两个属性:

include 值为字符串或者正则表达式匹配的组件name会被缓存。 exclude 值为字符串或正则表达式匹配的组件name不会被缓存,其它组件全部缓存。

``` 首先利用include实现,匹配到组件中定义的name,将进行缓存 image.png

image.png

当我们切换路由的时候就会发现,只有name为KeepAlive的这个组件被缓存了,其他路由被未被缓存,你可以在企业路由同样打印对应的生命周期。

image.png

其次我们再来利用exclude实现,匹配的组件name不会被缓存,其它组件全部缓存。 我们把include直接换成exclude,再次切换组件路由,我们会发现生命周期模块在执行一次生命周期created等生命周期之后,就没有执行了(有执行组件缓存的两个生命周期,只是我没打印),说明被组件换成了,而组件缓存模块一直在执行created等生命周期,而没执行组件缓存的两个生命周期了。

image.png

当然就是keep-alive组件缓存的使用方式,当然keep-alive的使用方式并不止这一种,欢迎大家留言讨论。

结束

对于本文章,你有任何疑问,可在评论区留言交流。另外,我自己建了一个前端技术交流群,群成员工作年限0-10年都有,如果想进前端技术交流群,可以加我微信fangdongdong_25,请备注掘金哦。