Vue 3 项目踩坑小计:`router-view` 缓存失效

1,113 阅读2分钟

在 Vue 3 项目中,使用 <KeepAlive> 缓存路由组件时,可能会遇到缓存不生效的问题。以下是常见原因及解决方法的总结。

1. <KeepAlive> 写法错误

错误示范:

vue复制

<keep-alive>
  <router-view></router-view>
</keep-alive>

正确写法:

vue复制

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

在 Vue 3 中,<KeepAlive> 需要通过插槽接收动态组件,而不是直接包裹 <router-view>

2. include 属性使用错误

<KeepAlive>include 属性需要指定组件的名称,而不是路由的名称。组件名称可以通过 <script setup name="ComponentName"> 来指定。例如:

vue复制

<script setup name="TemplateAllocation"></script>

然后在 <KeepAlive> 中使用:

vue复制

<keep-alive :include="['TemplateAllocation']">
  <component :is="Component"></component>
</keep-alive>

确保 include 中使用的是组件的名称。

Tip

非常重要的事情: vue 3.2.34 或以上的版本中,使用 <script setup> 的单文件组件会自动根据文件名生成对应的 name 选项,无需再手动声明。

3. 组件名称未正确设置

在 Vue 3 中,<script setup> 语法下,组件名称可以通过 defineOptions 设置。例如:

vue复制

defineOptions({
  name: 'TemplateAllocation'
})

如果未显式设置组件名称,Vue 会根据文件名推断组件名称。例如,文件名为 index.vue 时,组件名称会自动设置为 Index,这可能导致 include 属性不生效。

4. 多层嵌套路由缓存问题

在多层嵌套路由中,可以通过将所有 <router-view> 都通过 <KeepAlive> 包裹起来,并使用 includeexclude 属性来判断是否需要缓存。例如:

vue复制

<router-view v-slot="{ Component }">
  <keep-alive :include="cacheList">
    <component :is="Component" :key="route.fullPath" />
  </keep-alive>
</router-view>

这样可以实现嵌套路由的缓存。

5. 动态组件缓存问题

如果多个路由使用同一个组件,可以通过动态修改组件的名称来解决缓存问题。例如:

vue复制

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

这样可以确保每个路由的组件实例都有唯一的名称,从而正确缓存。

总结

在 Vue 3 项目中,使用 <KeepAlive> 缓存路由组件时,需要注意 <KeepAlive> 的写法、include 属性的使用、组件名称的设置、多层嵌套路由的处理以及动态组件的缓存问题。通过以上方法,可以有效解决 router-view 缓存失效的问题,提升用户体验和应用性能。