Vue 中 KeepAlive 内置缓存使用

KeepAlive 介绍及使用场景

KeepAlive 是 vue 中的内置组件,当多个组件动态切换时可以对实例状态进行缓存,用法如下

vue 复制代码
<router-view v-slot="{ Component }">
    <keep-alive>
    	<component :is="Component" />
    </keep-alive>    
 </router-view>

router-view 中定义了一个信号槽,来渲染跳转后的组件,将keep-alive 标签封装在 组件的外面,即可实现路由跳转组件的缓存效果

KeepAlive 使用实例

下图有两个组件 页面1 和 页面2,组件页面切换 通过 点击按钮 实现

页面1 是一个计数器,加一减一,默认初始值为 0;点击按钮 页面2 ,会跳转一个 含有输入框的页面,输入框默认为空;

正常情况下,组件切换都会将组件置为初始化状态,不会缓存历史数据;如当页面1 中通过触发 增加减少按钮将当前值置为 5 后,当切换到页面2 再切换至 页面1 ,当前值会被重置为0,原有历史数据并没有被缓存下来

而 keepAlive 可以在切换时将组件内的原有状态数据进行缓存;使用时只需要将需要缓存的组件外面包裹一层 <keepAlive></keepAlive> 标签即可,如下:

vue 复制代码
<template>
  <div class="main-test">


    <div style="margin-top:20px;margin-left: 20px;">
      <a-space>

        <a-button type="primary" style="color: blue; font-size: 14px" @click="changePageName"
          :disabled="pageName === 'A'">
          页面1
        </a-button>
        <a-button type="primary" style="color: blue; font-size: 14px" @click="changePageName"
          :disabled="pageName === 'B'">
          页面2
        </a-button>

      </a-space>
    </div>
    <keep-alive>
      <Page1 v-if="pageName === 'A'" style="margin-left: 20px; font-size: 16px; margin-top: 25px;">
      </Page1>
    </keep-alive>
    <keep-alive>
      <Page2 v-if="pageName === 'B'" style="margin-left: 20px; font-size: 16px; margin-top: 25px;">
      </Page2>
    </keep-alive>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import Page1 from '@/components/test/Page1.vue';
import Page2 from '@/components/test/Page2.vue';

const pageName = ref('A')

function changePageName() {
  pageName.value = pageName.value === 'A' ? 'B' : 'A'
}

</script>

Page1 组件

vue 复制代码
<template>
    <div style="color: black;">
        当前值为{{ pageName }}
        <div style="margin-top: 20px;">
            <a-space>

                <a-button @click="addNum" type="primary">
                    增加
                </a-button>
                <a-button @click="minusNum" type="primary">
                    减少
                </a-button>
            </a-space>
        </div>
    </div>
</template>
  
<script setup>
import { ref } from 'vue'

const pageName = ref(0)

function addNum() {
    pageName.value += 1
}
function minusNum() {
    pageName.value -= 1
}

</script>
  
  
<style scoped lang="less">
.main-test {
    font-size: large;
    color: red;
    font-weight: bold;
}
</style>

Page2 组件

vue 复制代码
<template>
    <div style="color: black;">
        输入值
        <a-input v-model:value="pageName" style="margin-top: 20px; width: 300px;" placeholder="请输入需要添加的值"></a-input>
    </div>
</template>
  
<script setup>
import { ref } from 'vue'
const pageName = ref('')

</script>
  
  
<style scoped lang="less">
.main-test {
    font-size: large;
    color: red;
    font-weight: bold;
}
</style>

页面 Page1 和 页面 Page2 组件的外层都加了一层 <keep-alive></keep-alive> 标签,这样无论从页面1切换到 2 还是2 切换到1 ,两个组件内的数据状态都会得到缓存,不需要重新加载

借助 Include /Exclude 属性 条件缓存

KeepAlive 默认缓存标签内所有组件,提供 includeexclude 属性可以实现条件缓存,支持逗号分隔、正则表达式,或者类型数组等三种形式

具体用法如下:

vue 复制代码
<!-- 逗号隔离的字符串,匹配 name 为 a 或 b 的组件  -->
<KeepAlive include="a,b">
  <component :is="view" />
</KeepAlive>

<!--正则表达式 ,匹配 name 不为 a 或 b 的组件-->
<KeepAlive :exclude="/a|b/">
  <component :is="view" />
</KeepAlive>

<!--数组 ,匹配 name 为 a 或 b 的组件 -->
<KeepAlive :include="['a', 'b']">
  <component :is="view" />
</KeepAlive>

上面属性内容匹配的都是组件 的 name option ,当组件需要被 keepAlive 条件缓存时,都需要指定 组件的 name

vue2 中 单文件 组件 指定 name 方式如下

vue 复制代码
<template>
 <div>
 </div>
</template>
<script>
export default {
  name: 'test'
}
</script>

vue3 中 单文件 组件 name 指定,自 3.2.34 以后版本自动将 文件的文件名指定为 name,移除了手动声明方式

max 指定 最大缓存实例 次数

<KeepAlive> 中 通过指定 max 属性来限制组件实例的最大缓存次数,当缓存实例次数达到max 值,则将最少访问 实例 销毁 为新示例创建预留空间

vue 复制代码
<KeepAlive :max="10">
  <component :is="activeComponent" />
</KeepAlive>
实例缓存的钩子函数

被 KeepAlive 缓存的组件实例,当组件挂载或销毁时会分别触发 activated()deactivated()钩子 函数,而不是 unmounted()mounted()

如果要在实例挂载或销毁时做一些操作,可以把相关逻辑写入两个钩子函数里:

vue 复制代码
<script setup>
import { onActivated, onDeactivated } from 'vue'

onActivated(() => {
  // called on initial mount
  // and every time it is re-inserted from the cache
})

onDeactivated(() => {
  // called when removed from the DOM into the cache
  // and also when unmounted
})
</script>
参考

https://vuejs.org/guide/built-ins/keep-alive.html#basic-usage

相关推荐
完球了7 分钟前
【Day02-JS+Vue+Ajax】
javascript·vue.js·笔记·学习·ajax
前端没钱8 分钟前
若依Nodejs后台、实现90%以上接口,附体验地址、源码、拓展特色功能
前端·javascript·vue.js·node.js
爱喝水的小鼠14 分钟前
AJAX(一)HTTP协议(请求响应报文),AJAX发送请求,请求问题处理
前端·http·ajax
叫我:松哥30 分钟前
基于机器学习的癌症数据分析与预测系统实现,有三种算法,bootstrap前端+flask
前端·python·随机森林·机器学习·数据分析·flask·bootstrap
让开,我要吃人了33 分钟前
HarmonyOS鸿蒙开发实战(5.0)网格元素拖动交换案例实践
前端·华为·程序员·移动开发·harmonyos·鸿蒙·鸿蒙开发
谢尔登41 分钟前
Webpack 和 Vite 的区别
前端·webpack·node.js
谢尔登41 分钟前
【Webpack】Tree Shaking
前端·webpack·node.js
过期的H2O21 小时前
【H2O2|全栈】关于CSS(4)CSS基础(四)
前端·css
纳尼亚awsl1 小时前
无限滚动组件封装(vue+vant)
前端·javascript·vue.js
八了个戒1 小时前
【TypeScript入坑】TypeScript 的复杂类型「Interface 接口、class类、Enum枚举、Generics泛型、类型断言」
开发语言·前端·javascript·面试·typescript