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

相关推荐
LYFlied19 小时前
TS-Loader 源码解析与自定义 Webpack Loader 开发指南
前端·webpack·node.js·编译·打包
yzp011219 小时前
css收集
前端·css
暴富的Tdy19 小时前
【Webpack 的核心应用场景】
前端·webpack·node.js
遇见很ok19 小时前
Web Worker
前端·javascript·vue.js
风舞红枫20 小时前
前端可配置权限规则案例
前端
前端不太难20 小时前
RN Navigation vs Vue Router:从架构底层到工程实践的深度对比
javascript·vue.js·架构
zhougl99620 小时前
前端模块化
前端
暴富暴富暴富啦啦啦20 小时前
Map 缓存和拿取
前端·javascript·缓存
天问一20 小时前
前端Vue使用js-audio-plugin实现录音功能
前端·javascript·vue.js
在路上看风景20 小时前
02. 缓存行
缓存