Administrator
发布于 2022-04-14 / 82 阅读 / 0 评论 / 0 点赞

在vue3/vue-router4下使用keep-alive

在vue3/vue-router4下使用keep-alive

旧版的语法已经失效

<keep-alive>
    <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>

新版官方推荐使用

<router-view>、<keep-alive> 和 <transition>

transition 和 keep-alive 现在必须通过 v-slot API 在 RouterView 内部使用:

<router-view v-slot="{ Component }">
  <transition>
    <keep-alive>
      <component :is="Component" />
    </keep-alive>
  </transition>
</router-view>

官方推荐的方式是只有keep-alive模式,却没有不需要keep-alive的使用方法

错误示范

这样会造成所有页面都没有缓存,还不知道原因。

<router-view v-slot="{ Component }" v-if="$route.meta.keepAlive">
    <keep-alive>
      <component :is="Component" >
        <p>缓存页面</p>
      </component>
    </keep-alive>
  </router-view>
  <router-view v-slot="{ Component }" v-if="!$route.meta.keepAlive">
    <component :is="Component" >
      <p>没有缓存的页面</p>
    </component>
  </router-view>

解决方案1

<router-view v-slot="{ Component }">
    <keep-alive v-if="$route.meta.keepAlive">
      <component :is="Component" >
        <p>缓存页面</p>
      </component>
    </keep-alive>
    <component :is="Component" v-if="!$route.meta.keepAlive">
      <p>没有缓存的页面</p>
    </component>
  </router-view>

使用解决方案1,在某些情况会有问题
假设A、B页面是缓存,C页面是不需要缓存。A、B间跳转不会有问题,A、B跳转C页面再返回时候缓存会失效一次。总结就是非缓存和缓存页面跳转会造成缓存的页面失效,只有再跳转缓存的页面才恢复正常。
这样可能和我们所预期的效果会不太一致。

解决方案2

<template>
  <router-view v-slot="{ Component }">
    <keep-alive :include="includeList">
      <component :is="Component"></component>
    </keep-alive>
  </router-view>

</template>
 
<script lang="ts">
//使用动态include解析
//app.vue文件
  export default {
    name: 'App',
    data(){
      return {
        includeList : []
      }
    },
    watch:{
      $route(to:any) {
        //监听路由变化,把配置路由中keepAlive为true的name添加到include动态数组中
        const that:any = this;
        if(to.meta.keepAlive && that.includeList.indexOf(to.name) === -1){
          that.includeList.push(to.name);
        }
      }
    }
  }
</script>

评论