Vue3手动清理keep-alive组件缓存的方法详解

 更新时间:2024年04月03日 08:59:58   作者:xinfei  
这篇文章主要为大家详细介绍了Vue3中手动清理keep-alive组件缓存的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

Vue3中手动清理keep-alive组件缓存的一个解决方案

源码

  if ((process.env.NODE_ENV !== 'production') || __VUE_PROD_DEVTOOLS__) {
        instance.__v_cache = cache;
    }

    //省略一些代码...

    function pruneCacheEntry(key) {
        const cached = cache.get(key);
        if (!current || cached.type !== current.type) {
            unmount(cached);
        }
        else if (current) {
            // current active instance should no longer be kept-alive.
            // we can't unmount it now but it might be later, so reset its flag now.
            resetShapeFlag(current);
        }
        cache.delete(key);
        keys.delete(key);
    }

这里表明我们有两种修改方案:  

方案一:注释 instance.__v_cache = cache; 这行代码的判断条件,也就是注释掉它的if判断,这样无论在什么环境,我们都可以取到__v_cache对象,这样就可以按照上一篇的方案来解决手动释放的问题

方案二:注意到源码中的pruneCacheEntry函数就是通过key来释放缓存,所以如果仅仅是想通过key来释放缓存,那么可以通过将pruneCacheEntry函数暴露出来实现我们的要求

方案一

修改vue.config.js,在文件开头添加下面的代码:  

    const path = require("path");
    const fs = require("fs");
    try {
      const vue_bundler_file = path.resolve(
        __dirname,
        "node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js"
      );
      //使用同步读取文件
      let data = fs.readFileSync(vue_bundler_file, "utf8");
      //如果未添加过
      if (data.indexOf("//__v_cache") < 0) {
        console.log("正在修改源码文件:", vue_bundler_file);
        //先找到__v_cache变量的位置
        let index = data.indexOf("__v_cache");
        if (index >= 0) {
          // 继续往前找if关键字
          index = data.lastIndexOf("if ", index);
          if (index >= 0) {
            //从上一个位置开始
            index -= 1;
            //然后放一个注释
            const comment = " //__v_cache ";
            //然后拼接
            data = data.substring(0, index) + comment + data.substring(index);

            //继续往后找下一个大括号 }
            index = data.indexOf("}", index);
            if (index >= 0) {
              //从上一个位置开始
              index -= 1;
              //然后拼接
              data = data.substring(0, index) + comment + data.substring(index);
            }

            fs.writeFileSync(vue_bundler_file, data, "utf8");
          }
        }
      }
    } catch (er) {
      console.error(er.message);
    }

然后重新启动运行项目,就可以按照上一篇的方式,通过 __v_cache 对象来手动清理keep-alive的缓存了。  

    export default {
      setup() {
        const instance = getCurrentInstance();
        const handler = new KeepAliveHandler();
        onMounted(() => {
          const keepAlive = instance.refs.keepAlive;
          handler.bind(keepAlive);
        });
        const remove = (key) => {
          handler.remove(key);
        };

        return {
          remove,
        };
      },
    };

如果打开 node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js 文件,搜索 __v_cache ,会看到这样的代码片段:

方案二

在 vue.config.js 中开头添加如下代码:

    const path = require("path");
    const fs = require("fs");
    try {
      const vue_bundler_file = path.resolve(
        __dirname,
        "node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js"
      );
      //使用同步读取文件
      const data = fs.readFileSync(vue_bundler_file, "utf8");
      //如果未添加过
      if (data.indexOf("sharedContext.$pruneCacheEntry") < 0) {
        console.log("正在修改源码文件:", vue_bundler_file);
        //先找到__v_cache变量的位置
        let index = data.indexOf("__v_cache");
        if (index >= 0) {
          // 继续找下一个大括号 }
          index = data.indexOf("}", index);
          if (index >= 0) {
            //从下一个位置开始
            index += 1;
            //然后放一个可以释放的函数
            const remove =
              "        sharedContext.$pruneCacheEntry = (key) => cache.get(key) && pruneCacheEntry(key);";
            //然后拼接
            const result =
              data.substring(0, index) +
              "\r\n" +
              remove +
              "\r\n" +
              data.substring(index);
            fs.writeFileSync(vue_bundler_file, result, "utf8");
          }
        }
      }
    } catch (er) {
      console.error(er.message);
    }
    const path = require("path");
    const fs = require("fs");
    try {
      const vue_bundler_file = path.resolve(
        __dirname,
        "node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js"
      );
      //使用同步读取文件
      const data = fs.readFileSync(vue_bundler_file, "utf8");
      //如果未添加过
      if (data.indexOf("sharedContext.$pruneCacheEntry") < 0) {
        console.log("正在修改源码文件:", vue_bundler_file);
        //先找到__v_cache变量的位置
        let index = data.indexOf("__v_cache");
        if (index >= 0) {
          // 继续找下一个大括号 }
          index = data.indexOf("}", index);
          if (index >= 0) {
            //从下一个位置开始
            index += 1;
            //然后放一个可以释放的函数
            const remove =
              "        sharedContext.$pruneCacheEntry = function(key) {\r\n" +
              "            const cached = cache.get(key);\r\n" +
              "            if (cached) {\r\n" +
              "                if (cached.key == current?.key) {\r\n" +
              "                    resetShapeFlag(current);\r\n" +
              "                } else {\r\n" +
              "                    unmount(cached);\r\n" +
              "                }\r\n" +
              "                cache.delete(key);\r\n" +
              "                keys.delete(key);\r\n" +
              "            }\r\n" +
              "        }\r\n"
            //然后拼接
            const result =
              data.substring(0, index) +
              "\r\n" +
              remove +
              "\r\n" +
              data.substring(index);
            fs.writeFileSync(vue_bundler_file, result, "utf8");
          }
        }
      }
    } catch (er) {
      console.error(er.message);
    }

之后,我们项目重新运行后,就可以通过ref取到keep-alive组件的引用,然后使用这个引用对象直接使用$pruneCacheEntry函数来删除指定key的缓存了:  

    this.$refs.keepAlive.$pruneCacheEntry("key")

如果打开 node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js 文件,搜索 __v_cache ,会看到这样的代码片段:

结语

目前,目前还没有找到更好的解决方案,我自己采用的是第二种方案,算是暂时解决了问题,当然,两种方案可以结合使用。

到此这篇关于Vue3手动清理keep-alive组件缓存的方法详解的文章就介绍到这了,更多相关Vue3清理keep-alive组件缓存内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue3的hooks用法总结

    vue3的hooks用法总结

    vue3中的hooks其实是函数的写法,就是将文件的一些单独功能的js代码进行抽离出来,放到单独的js文件中,这篇文章主要介绍了一文掌握vue3中hooks的介绍及用法,需要的朋友可以参考下
    2023-04-04
  • Vue实现成绩增删案例思路详解

    Vue实现成绩增删案例思路详解

    这篇文章主要介绍了Vue实现成绩增删案例思路详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2025-05-05
  • vue实现页面滚动到底部刷新

    vue实现页面滚动到底部刷新

    这篇文章主要为大家详细介绍了vue实现页面滚动到底部刷新,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • antd form表单中如何嵌套自定义组件

    antd form表单中如何嵌套自定义组件

    这篇文章主要介绍了antd form表单中如何嵌套自定义组件问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • 详解如何在Vue项目中实现累加动画

    详解如何在Vue项目中实现累加动画

    这篇文章主要为大家详细介绍了如何在你的Vue项目中实现累加动画,文中的示例代码简洁易懂,具有一定的参考价值,感兴趣的小伙伴可以了解一下
    2023-06-06
  • vite.config.ts配置之自动导入element-puls方式

    vite.config.ts配置之自动导入element-puls方式

    这篇文章主要介绍了vite.config.ts配置之自动导入element-puls方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • 利用vue对比两组数据差异的可视化组件详解

    利用vue对比两组数据差异的可视化组件详解

    这篇文章主要给大家介绍了关于利用vue对比两组数据差异的可视化组件的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用vue具有一定的参考学习价值,需要的朋友可以参考下
    2021-09-09
  • vue2.0与bootstrap3实现列表分页效果

    vue2.0与bootstrap3实现列表分页效果

    这篇文章主要为大家详细介绍了vue2.0与bootstrap3实现列表分页效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • vue.js页面加载执行created,mounted的先后顺序说明

    vue.js页面加载执行created,mounted的先后顺序说明

    这篇文章主要介绍了vue.js页面加载执行created,mounted的先后顺序说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • vue.js中proxyTable 转发请求的实现方法

    vue.js中proxyTable 转发请求的实现方法

    今天小编就为大家分享一篇vue.js中proxyTable 转发请求的实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09

最新评论