vue3动态路由使用keepalive缓存问题

问题遇到的现象和发生背景

想写一个文章分类列表,通过后端传来的数据生成头部tab标签,然后点击标签跳转页面,这个页面使用的
是同一个组件,只是通过传入的id不同获取相应的数据,我希望在点击标签切换的时候之前的浏览不要消失,

问题相关代码,请勿粘贴截图

img


img

运行结果及报错内容

每次切换标签时,数据能够正常的刷新了,可以通过路由上的动态id获取数据,
但是页面并没有被缓存下来

我的解答思路和尝试过的方法

由于动态路由使用的都是同一个组件,直接缓存的话无法实现,因此在router-view上使用了$route.path作为key来保证
切换时是不同的返回

实现了一版,看看是否这个意思。我用的vue-cli建立的案例。整体目录结构如下图:

img

代码如下:

App.vue:


<template>
  <nav>
    <button @click="handleRoute(1)">动画</button>
    <button @click="handleRoute(2)">小说</button>
  </nav>
  <router-view v-slot="{ Component }">
    <keep>
      <component :is="Component"></component>
    </keep>
  </router-view>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";
import { useRouter } from "vue-router";
import Keep from "@/components/keep";
export default defineComponent({
  components: {
    Keep,
  },
  setup() {
    const router = useRouter();
    const handleRoute = (id: number) => {
      router.push({
        params: {
          id,
        },
      });
    };

    return {
      handleRoute,
    };
  },
});
</script>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;

  a {
    font-weight: bold;
    color: #2c3e50;

    &.router-link-exact-active {
      color: #42b983;
    }
  }
}
</style>

components/keep.ts:


import { defineComponent, h, cloneVNode, KeepAlive } from "vue";
import { useRoute } from "vue-router";

export default defineComponent({
  setup(props, { slots }) {
    const route = useRoute();
    return () => {
      console.log(route.fullPath, "00--");

      const component = (slots && slots.default?.())!;
      return h(KeepAlive, {}, () =>
        cloneVNode(component[0], { key: route.fullPath })
      );
    };
  },
});

views/HomeView.vue:


<template>
  <div class="home">
    <input v-model="input1" />
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";

export default defineComponent({
  name: "HomeView",
  setup() {
    const input1 = ref("");
    return {
      input1,
    };
  },
});
</script>

router/index.ts:


import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
import HomeView from "../views/HomeView.vue";

const routes: Array<RouteRecordRaw> = [
  {
    path: "/book/:id",
    name: "home",
    component: HomeView,
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;