wszyyo 2022-05-25 00:48 采纳率: 30%
浏览 580
已结题

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

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

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

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

img


img

运行结果及报错内容

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

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

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

  • 写回答

1条回答 默认 最新

  • v逆水行舟v 2022-05-25 09:03
    关注

    实现了一版,看看是否这个意思。我用的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;
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 6月2日
  • 已采纳回答 5月25日
  • 创建了问题 5月25日

悬赏问题

  • ¥15 soildworks装配体的尺寸问题
  • ¥100 有偿寻云闪付SDK转URL技术
  • ¥30 基于信创PC发布的QT应用如何跨用户启动后输入中文
  • ¥20 非root手机,如何精准控制手机流量消耗的大小,如20M
  • ¥15 远程安装一下vasp
  • ¥15 自己做的代码上传图片时,报错
  • ¥15 Lingo线性规划模型怎么搭建
  • ¥15 关于#python#的问题,请各位专家解答!区间型正向化
  • ¥15 unity从3D升级到urp管线,打包ab包后,材质全部变紫色
  • ¥50 comsol温度场仿真无法模拟微米级激光光斑