vue-router 动态页缓存不是问题

238 阅读1分钟

增强 Vue RouterRouterView & KeepAlive 功能。

背景

Vue Router 目前的 RouterView 组件在搭配 KeepAlive 组件时存在以下问题:

  1. 无法根据动态路由匹配进行相同组件实例不同参数的缓存
  2. 路由组件必须设置不同的 name 属性,否则重名组件会缓存异常

该插件致力于简单、高效的解决上述问题,且使用方式上与原组件除过模板引用方式存在差异外,其他功能均保持一致。

在线示例

安装

npm i vue-router-better-view

局部使用

<!-- layout.vue -->
<script setup lang="ts">
import { BetterRouterView } from 'vue-router-better-view'
</script>

<template>
  <main>
    <better-router-view />
  <main>
</template>

组件属性

export interface BetterRouterViewProps extends RouterViewProps {
  /**
   * 获取当前路由的视图组件标识,未设置或返回值为假值时与 `RouterView` 组件表现一致
   * @param route 当前路由
   * @returns 视图组件标识
   */
  resolveViewKey?: ResolveViewKey
}

示例

<script setup lang="ts">
import { BetterRouterView, type ResolveViewKey } from 'vue-router-better-view'

const resolveViewKey: ResolveViewKey = (route) => {
  // 如果 route.meta.singleton 为 true,则以路由的 path 作为视图组件标识
  if (route.meta.singleton) {
    return route.path
  }

  // 使用路由的 fullPath 作为视图组件标识
  return route.fullPath
}
</script>

<template>
  <main>
    <better-router-view
      v-slot="{ Component }"
      :resolve-view-key="resolveViewKey"
    >
      <!-- include、exclude 可以根据 resolveViewKey 的返回值进行缓存处理 -->
      <keep-alive>
        <component :is="Component" />
      </keep-alive>
    </better-router-view>
  </main>
</template>

模板引用

<script setup lang="ts">
+import { ref } from 'vue'

+const mainContent = ref<any>()
+const resolveMainContent = () => {
+  // 优先使用 inner 属性获取原组件引用,不存在时使用 mainContent.value 兜底
+  return mainContent.value?.inner || mainContent.value
+}
</script>

<template>
-        <component :is="Component" />
+        <component :is="Component" ref="mainContent" />
</template>