首页
归档
笔记
树洞
搜索
友言

文章详情

Interesting People Record Interesting.

/ JavaScript / 文章详情

完美解决vue3 keep-alive多个路由使用同一个组件的缓存问题

Sonder
2023-12-12
2380字
6分钟
浏览 (700)

之前页面少的话 用keep-live结合router-view,使用keep-live的include属性就可以自己决定keep-live缓存那些组件不缓存那些组件,直到遇到个问题。

平时写的代码如下:

复制代码
<router-view v-slot="{ Component, route }">

   <keep-alive :include="[...visitedViewPaths]">

   <component 

   :is="Component"/>

   </keep-alive>

</router-view>

其中 visitedViewPaths表示的是一个放Component name的数组,可以去看文档 https://cn.vuejs.org/guide/built-ins/keep-alive.html#include-exclude

如果配置的路由A用A组件,路由B用A组件,因为include属性是靠组件的name来决定缓存与不缓存的,还有这种情况,路由里配置的{ path: '/users/:id', component: User },这样的配置也是多个路由使用同一个组件的情况,现在这种路由对应的组件实例name是相同的,这就不好处理了,想到的解决方案如下:

复制代码
   <router-view v-slot="{ Component, route }">

       <keep-alive :include="[...visitedViewPaths]">

           <component 

             :is="formatComponentInstance(Component,route)"/>

       </keep-alive>

   </router-view>

   function formatComponentInstance(){
       component.type = {
           ...component.type,
           name:route.path,
       };
       return component;
   }

为什么要这么写,因为主要原因就是改个name的嘛,component.type放的是该组件对象,不能直接改,两个component.type所指向的对象是同一个,所以用一个新对象来。
以为解决了,结果报错,报啥错就不说了,我觉得应该是vue用那个弱引用map把组件对象当作key,存了一个其他数据,对象变了就取不到该数据了。
以为没法解决了,结果百度到了一个方法完美解决 https://blog.csdn.net/qq_42611074/article/details/127206469

思路还是一样,改组件name,这次不是改原组件name,直接新建一个组件出来,如下:

复制代码
<router-view v-slot="{ Component, route }">
   <keep-alive :include="[...visitedViewPaths]">
       <component 
           :is="formatComponentInstance(Component,route)"/>
   </keep-alive>
</router-view>

// 用来存已经创建的组件
const wrapperMap = new Map();
// 将router传个我们的组件重新换一个新的组件,原组件包里面
function formatComponentInstance(component, route) {
   let wrapper;
   if (component) {
       const wrapperName = route.path;
       if (wrapperMap.has(wrapperName)) {
           wrapper = wrapperMap.get(wrapperName);
       } else {
           wrapper = {
               name: wrapperName,
               render() {
                   return h(component);
               },
           };
           wrapperMap.set(wrapperName, wrapper);
       }
       return h(wrapper);
   }
}

其中 visitedViewPaths 是你自己的需要缓存的name列表,现在组件名字由你控制了,就已经解决了。多谢原文章大佬,https://blog.csdn.net/qq_42611074/article/details/127206469
总算是解决了这个疑难问题哇。

来源于:https://blog.dumogu.top/post/x2IlJjmV9

下一篇 / vue3代码笔记

🎯 相关文章

💡 推荐文章

🕵️‍♂️ 评论 (0)