增强 Vue Router 的 RouterView & KeepAlive 功能。
背景
Vue Router 目前的 RouterView 组件在搭配 KeepAlive 组件时存在以下问题:
- 无法根据动态路由匹配进行相同组件实例不同参数的缓存
- 路由组件必须设置不同的
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>