keep-alive组件缓存

时间:2024-10-03 14:22:47

 目录

前言

动态组件

扩展

 关于is

1.动态组件

的用法

组件缓存

扩展

跟keep-alive有关的生命周期是哪些?

activated

deactivated


前言

在开发Vue项目的时候,大部分组件是没必要多次渲染的,所以Vue提供了一个

内置组件keep-alive来缓存组件内部状态,避免重新渲染。

keep-alive是一个抽象组件:它自身不会渲染一个DOM元素,也不会出现在父组件链中;

使用keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们

动态组件

多个组件使用同一个挂载点,并动态切换,这就是动态组件

栗子:完成一个注册功能页面, 2个按钮切换, 一个填写注册信息, 一个填写用户简介信息

  1. <template>
  2. <div>
  3. <button @click="comName = 'UserName'">账号密码填写</button>
  4. <button @click="comName = 'UserInfo'">个人信息填写</button>
  5. <p>下面显示注册组件-动态切换:</p>
  6. <div style="border: 1px solid red;">
  7. <component :is="comName"></component>
  8. </div>
  9. </div>
  10. </template>
  11. <script>
  12. // 目标: 动态组件 - 切换组件显示
  13. // 场景: 同一个挂载点要切换 不同组件 显示
  14. // 1. 创建要被切换的组件 - 标签+样式
  15. // 2. 引入到要展示的vue文件内, 注册
  16. // 3. 变量-承载要显示的组件名
  17. // 4. 设置挂载点<component :is="变量"></component>
  18. // 5. 点击按钮-切换comName的值为要显示的组件名
  19. import UserName from '../components/01/UserName'
  20. import UserInfo from '../components/01/UserInfo'
  21. export default {
  22. data(){
  23. return {
  24. comName: "UserName"
  25. }
  26. },
  27. components: {
  28. UserName,
  29. UserInfo
  30. }
  31. }
  32. </script>

结论:vue内置component组件, 配合is属性, 设置要显示的组件名字

扩展

 关于is

1.动态组件

​ componentName可以是在本页面已经注册的局部组件名和全局组件名,也可以是一个组件的选项对象。 当控制componentName改变时就可以动态切换选择组件。

2.is的用法

有些HTML元素,诸如 <ul>、<ol>、<table>和<select>,对于哪些元素可以出现在其内部是有严格限制的。 ​ 而有些HTML元素,诸如 <li>、<tr> 和 <option>,只能出现在其它某些特定的元素内部。

  1. <ul>
  2. <card-list></card-list>
  3. </ul>
  4. ​// 所以上面会被作为无效的内容提升到外部,并导致最终渲染结果出错。应该这么写:
  5. <ul>
  6. <li is="cardList"></li>
  7. </ul>

组件缓存

组件切换会导致组件被频繁销毁和重新创建, 性能不高

使用Vue内置的keep-alive组件, 可以让包裹的组件保存在内存中不被销毁

演示1: 可以先给和 注册created和destroyed生命周期事件, 观察创建和销毁过程

演示2: 使用keep-alive内置的vue组件, 让动态组件缓存而不是销毁 语法: ​ Vue内置的keep-alive组件 包起来要频繁切换的组件 

  1. <div style="border: 1px solid red;">
  2. <!-- Vue内置keep-alive组件, 把包起来的组件缓存起来 -->
  3. <keep-alive>
  4. <component :is="comName"></component>
  5. </keep-alive>
  6. </div>

在vue-router中的应用 

  1. <keep-alive : include="whiteList" : exclude="blackList">
  2. <router-view></router-view>
  3. </keep-alive>

include定义缓存白名单,keep-alive会缓存命中的组件;

exclude定义缓存黑名单,被命中的组件将不会被缓存;
很多时候也可以配合路由的meta属性使用

  1. export default[
  2. {
  3. path:'/',
  4. name:'home',
  5. components:Home,
  6. meta:{
  7. keepAlive:true //需要被缓存的组件
  8. },
  9. {
  10. path:'/book',
  11. name:'book',
  12. components:Book,
  13. meta:{
  14. keepAlive:false //不需要被缓存的组件
  15. }
  16. ]
  17. <keep-alive>
  18. <router-view v-if="this.$"></router-view>
  19. <!--这里是会被缓存的组件-->
  20. </keep-alive>
  21. <keep-alive v-if="!this.$"></keep-alive>
  22. <!--这里是不会被缓存的组件-->

补充生命周期:     被缓存的组件不再创建和销毁, 而是激活和非激活

  • activated - 激活
  • deactivated - 失去激活状态

结论: keep-alive可以提高组件的性能, 内部包裹的标签不会被销毁和重新创建, 触发激活和非激活的生命周期方法 

扩展

跟keep-alive有关的生命周期是哪些?

生命周期函数:在被keep-alive包含的组件/路由中,会多出两个生命周期的钩子:activated 与 deactivated。

  • activated

activated钩子:**在在组件第一次渲染时会被调用,之后在每次缓存组件被激活时调用。

Activated钩子调用时机:** 第一次进入缓存路由/组件,在mounted后面,beforeRouteEnter守卫传给 next 的回调函数之前调用,并且给因为组件被缓存了,再次进入缓存路由、组件时,不会触发这些钩子函数,beforeCreate created beforeMount mounted 都不会触发

  • deactivated

deactivated钩子:**组件被停用(离开路由)时调用。

deactivated钩子调用时机:使用keep-alive就不会调用beforeDestroy(组件销毁前钩子)和destroyed(组件销毁),因为组件没被销毁,被缓存起来了,这个钩子可以看作beforeDestroy的替代,如果你缓存了组件,要在组件销毁的的时候做一些事情,可以放在这个钩子里,组件内的离开当前路由钩子beforeRouteLeave => 路由前置守卫 beforeEach =>全局后置钩子afterEach => deactivated 离开缓存组件 => activated 进入缓存组件(如果你进入的也是缓存路由)