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

平时写的代码如下:

 1    <router-view v-slot="{ Component, route }">
 2
 3        <keep-alive :include="\[...visitedViewPaths\]">
 4
 5            <component 
 6
 7              :is="Component"/>
 8
 9        </keep-alive>
10
11    </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是相同的,这就不好处理了,想到的解决方案如下:

 1    <router-view v-slot="{ Component, route }">
 2
 3        <keep-alive :include="\[...visitedViewPaths\]">
 4
 5            <component 
 6
 7              :is="formatComponentInstance(Component,route)"/>
 8
 9        </keep-alive>
10
11    </router-view>
12  
13    function formatComponentInstance(){
14        component.type = {
15            ...component.type,
16            name:route.path,
17        };
18        return component;
19    }

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

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

 1<router-view v-slot="{ Component, route }">
 2    <keep-alive :include="\[...visitedViewPaths\]">
 3        <component 
 4            :is="formatComponentInstance(Component,route)"/>
 5    </keep-alive>
 6</router-view>
 7
 8const wrapperMap = new Map();
 9
10function formatComponentInstance(component, route) {
11    let wrapper;
12    if (component) {
13        const wrapperName = route.path;
14        if (wrapperMap.has(wrapperName)) {
15            wrapper = wrapperMap.get(wrapperName);
16        } else {
17            wrapper = {
18                namewrapperName,
19                render() {
20                    return h(component);
21                },
22            };
23            wrapperMap.set(wrapperNamewrapper);
24        }
25        return h(wrapper);
26    }
27}

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

个人笔记记录 2021 ~ 2025