Vue应用——关于keep-alive

591 阅读4分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金

闲时要有吃紧的心思,忙时要有悠闲的趣味

目录

前言

返回目录

  作为一个vue为主要技术栈的前端,keep-alive是很常用的一个内置组件。下面我们来了解一下其使用和注意事项。

正文

一、keep-alive介绍

返回目录

keep-alive是什么

  keep-alive是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中;使用keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。主要用于保留组件状态或避免重新渲染。

使用场景

  用户在某个列表页面选择筛选条件过滤出一份数据列表,由列表页面进入数据详情页面,再返回该列表页面。 如果未使用keep-alive组件,则在页面回退时仍然会重新渲染页面,我们希望:

  • 列表页点击商品跳转到详情,返回后仍显示原有信息,保留用户的筛选(或选中)状态

  keep-alive就是用来解决这种场景的。

  当然keep-alive不仅仅是能够保存页面/组件的状态这么简单,它还可以避免组件反复创建和渲染,有效提升系统性能。 总的来说,keep-alive用于保存组件的渲染状态。

二、keep-alive的用法

返回目录

keep-alive的三个参数

  • include - string | RegExp | Array:定义缓存白名单,只有名称匹配的组件会被缓存(2.1.0 版本后)。

  • exclude - string | RegExp | Array:定义缓存黑名单,任何名称匹配的组件都不会被缓存, 优先级大于include(2.1.0 版本后)。

  • max - number | string:最定义缓存组件上限,超出上限使用LRU的策略置换缓存数据。

在动态组件中的应用

<keep-alive :include="whiteList" :exclude="blackList" :max="amount">
    <component :is="currentComponent"></component>
</keep-alive>

  不过此种方式并无太大的实用意义。

在vue-router中的应用

  • 在vue2中,可以直接包裹
<keep-alive>
    <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
  • 在vue3中,旧版的语法已经失效,新版官方推荐使用:

transition 和 keep-alive 现在必须通过 v-slot API 在 RouterView 内部使用:

<router-view v-slot="{ Component }">
    <transition>
        <keep-alive>
            <component :is="Component" />
        </keep-alive>
    </transition>
</router-view>

keep-alive的生命周期

  • 初次进入时
  1. 触发 setup > beforeCreate > created > beforeMount > mounted > activated

  2. 退出后触发 deactivated

  • 再次进入
  1. 触发 beforeUpdate > updated > activated

  2. 退出后触发 deactivated

  一般的组件,每一次加载都会有完整的生命周期,即生命周期里面对应的钩子函数都会被触发。

  被keep-alive包裹的组件却不是这样,不再进入$mount过程,mounted之前的所有钩子函数(beforeCreate、created、mounted)都不再执行。它有自己独有的两个生命周期:

  • actived 当keep-alive包含的组件再次渲染的时候触发。
  • deactived 当keep-alive包含的组件销毁的时候触发

  因此,在使用keep-alive时,只执行一次的放在 mounted 中;组件每次进去执行的方法放在 activated 中。

三、keep-alive使用的注意事项

返回目录

include无效

  1. 检查版本

  确定当前的vue版本的是2.1+, 因为include和exclude是vue2.1.0新增的两个属性.

  查看 package.json

"vue": "^2.5.2",
  1. 检查name

  注意, 不是 router.js 中的 name , 而是单个 vue 组件中的 name 属性.

  建议将 router.js 中的 namevue 组件的 name 保持一致, 不要混乱.

export default {
    name: "index"
}
  1. 多层嵌套

  凡有超过两个以上的router-view且是父子级关系, 请都加上keep-alive, 只加一个不会生效.

// app.vue

// other.vue

总结

返回目录

与诸君共勉,为自己加油!

参考文档

后记:Hello 小伙伴们,如果觉得本文还不错,记得点个赞或者给个 star,你们的赞和 star 是我编写更多更丰富文章的动力!GitHub 地址

文档协议

db 的文档库db 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
基于github.com/danygitgit上的作品创作。
本许可协议授权之外的使用权限可以从 creativecommons.org/licenses/by… 处获得。