可控制缓存销毁的 keepAlive 组件实现详解

 更新时间:2022年10月14日 08:53:35   作者:我的代码果然有问题  
这篇文章主要为大家介绍了可控制缓存销毁的 keepAlive 组件实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

简介

关于 Vue 的 KeepAlive

<KeepAlive> 是一个内置组件,它的功能是在多个组件间动态切换时 缓存 被移除的组件实例

我们可以利用这一特性来解决当路由切换时页面组件被销毁的问题,常见的业务场景有表单缓存,列表缓存定位,返回时保持状态等,网上有很多教程涉及,但是对如何自主控制缓存的组件销毁这一块大多讲的不是很清晰。

本文会以初学者的角度出发,一步一步带你了解 keepAlive 的特性并实现一个可以自主控制什么时候销毁缓存页面的 keepAlive 组件 —— app-router-view

思路

在编写这一组件时我们的思路是先在路由配置中加入缓存标识,然后在<router-view> 组件里加上<KeepAlive>标签,然后通过缓存标识判断是否缓存该组件,为了操作缓存的销毁,我们会用到 include 属性,通过操作 include 里的组件名实现自主销毁组件,以下是具体实现步骤。

在 Routes 中添加 keepAlive 缓存标识

const routes = [
    {
        path: '/index',
        name: 'index',
        component: () => import('@/views/index.vue'),
        meta: {
            title: '首页',
            keepAlive: false // 缓存标识
        }
    }
]

创建 app-router-view 组件

<template>
    <router-view v-slot="{ Component, route }">
        <keep-alive>
            <component :is="Component" v-if="route.meta.keepAlive"/>
        </keep-alive>
        <component :is="Component" v-if="!route.meta.keepAlive"/>
    </router-view>
</template>

这就是大家平时看教程比较常见的模式了,也能实现一些简单的需求,但还存在问题,就是当我们不需要缓存时候无法手动清除缓存,等会继续完善,这里先给大家简单介绍下<router-view> 的 v-slot 和标签里的 :is 是做什么的,这两个东西工作中并不常用,新同学可能比较陌生,这里也简单科普下。

router-view 中的 v-slot

简单说 v-slot 可以让我们方便的拿到路由标签包裹的组件和路由对象

主要用于方便我们使用 <transition><keep-alive> 组件来包裹我们自己的组件

标签里的 :is

官网介绍是用于绑定动态组件,简单说就是可以让标签转化为我们指定的 vue 组件

实现手动清除页面缓存

这里简单说下思路,<keep-alive> 标签上有 include 属性,会接收一个数组,数组里的值是我们要缓存页面的组件名,我们可以通过操作 include 的值来手动销毁我们的缓存页面。

这里需要特别注意这个组件名,没有理解好这一块实践中就会出现各种奇奇怪怪的问题!!!

组件名指的是 vue 组件定义时的那个命名,同时我们 routes 里定义的 name 需要与之对应,否则找不到关系,以下图为例,默认情况下,我们 vue 的文件名就是我们最终引入的组件名,即 list-one 与 list-two 就是需要我们维护在 routes 中的名字

了解了这一点后我们来开始代码实现

定义组件名的方法

一般情况下我们可以通过文件名称来做组件名,但是很多时候我们会遇到文件名称一样的问题,这时候就需要我们自定义组件名了,这里推荐两种方法原生模式和插件模式

  • 原生模式
<script> 
export default { 
    name: 'component-name' // 你的组件名 
} 
</script>
  • 插件模式

使用 vite-plugin-vue-setup-extend 插件扩展语法糖

// 安装插件
npm i unplugin-vue-components -D     
// 在页面 script setup 标签中定义 name
<script setup name="component-name">
// This starter template is using Vue 3 <script setup> SFCs
// ...
</script>

配置好路由 name 与组件 name 对应关系

{
    path: '/list-one',
    name: 'list-one',
    component: () => import('@/views/list-one.vue'),
    meta: {
        title: '列表 1',
        keepAlive: false
    }
},
{
    path: '/list-two',
    name: 'list-two',
    component: () => import('@/views/list-two.vue'),
    meta: {
        title: '列表 2',
        keepAlive: true
    }
}

在 pinia 或者 vuex 中定义好操作缓存列表的方法

我这里以 pinia 为例,创建 useKeepAliverStore 模块,通过 add , 与 remove 操作缓存列表

/**
 * @description: 缓存控制
 */
 export const useKeepAliverStore = defineStore('keepAliver', {
    state: () => ({
        caches: []
    }),
    getters: {},
    actions: {
        add(name) {
            if (!this.caches.includes(name)) {
                this.caches.push(name)
            }
        },
        remove(name) {
            this.caches = this.caches.filter((item) => item !== name)
        },
        clear() {
            this.caches = []
        }
    }
})

添加路由守卫,在页面进入时维护缓存列表

import { useKeepAliverStore } from '@/store/modules/keepAliver'
export function setupKeepAliver(router) {
    router.beforeEach((to, from, next) => {
        if (to.meta.keepAlive) {
            console.log('keepAliver')
            const { add } = useKeepAliverStore()
            add(to.name)
        }
        next()
    })
}

调整组件,维护好 include

<script setup>
// This starter template is using Vue 3 <script setup> SFCs
import { useKeepAliverStore } from '@/store/modules/keepAliver'
const { caches } = storeToRefs(useKeepAliverStore())
</script>
<template>
    <router-view v-slot="{ Component, route }">
        <keep-alive :include="caches">
            <component
                :is="Component"
                v-if="route.meta.keepAlive"
                :key="route.name"
            />
        </keep-alive>
        <component
            :is="Component"
            v-if="!route.meta.keepAlive"
            :key="route.name"
        />
    </router-view>
</template>

这样就大功告成啦,当我们想要销毁某个页面,只要调用下 remove 方法移除 caches 里对应的组件名,就可以销毁该页面的缓存了

demo地址:jyliyue/keep-alive-demo (github.com)

以上就是可控制缓存销毁的 keepAlive 组件实现详解的详细内容,更多关于可控制缓存销毁keepAlive组件的资料请关注脚本之家其它相关文章!

相关文章

  • vue如何定义全局变量和全局方法实例代码

    vue如何定义全局变量和全局方法实例代码

    在项目中经常会复用一些变量和函数,比如用户的登录token,用户信息等,这时将它们设为全局的就显得很重要了,下面这篇文章主要给大家介绍了关于vue如何定义全局变量和全局方法的相关资料,需要的朋友可以参考下
    2023-04-04
  • IDEA创建Vue项目的两种方式总结

    IDEA创建Vue项目的两种方式总结

    这篇文章主要介绍了IDEA创建Vue项目的两种方式总结,具有很好的参考价值,希望对大家有所帮助。
    2023-04-04
  • vuex页面刷新数据丢失解决方法详解

    vuex页面刷新数据丢失解决方法详解

    这篇文章主要为大家介绍了vuex页面刷新数据丢失解决方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • 关于Vue中keep-alive的作用及使用方法

    关于Vue中keep-alive的作用及使用方法

    keep-alive是Vue的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,该组件将不会销毁,这篇文章主要介绍了关于Vue中keep-alive的作用是什么?怎么使用,需要的朋友可以参考下
    2023-04-04
  • Vue+Element实现表格编辑、删除、以及新增行的最优方法

    Vue+Element实现表格编辑、删除、以及新增行的最优方法

    这篇文章主要为大家详细介绍了Vue+Element实现表格的编辑、删除、以及新增行的最优方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • 浅谈关于.vue文件中style的scoped属性

    浅谈关于.vue文件中style的scoped属性

    本篇文章主要主要介绍了浅谈关于.vue文件中style的scoped属性,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • 基于Vue2.0和Typescript实现多主题切换的示例

    基于Vue2.0和Typescript实现多主题切换的示例

    本文主要介绍了基于Vue2.0和Typescript实现多主题切换的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • vue组件(全局,局部,动态加载组件)

    vue组件(全局,局部,动态加载组件)

    组件是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。这篇文章主要介绍了vue组件(全局,局部,动态加载组件),需要的朋友可以参考下
    2018-09-09
  • ElementUI之Message功能拓展详解

    ElementUI之Message功能拓展详解

    这篇文章主要介绍了ElementUI之Message功能拓展详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • vue3使用elementPlus进行table合并处理的示例详解

    vue3使用elementPlus进行table合并处理的示例详解

    虚拟数据中公司下有多个客户,公司一样的客户,公司列需要合并,客户如果一样也需要合并进行展示,所以本文给大家介绍了vue3使用elementPlus进行table合并处理的实例,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2024-02-02

最新评论