An extension for Vue Router's RouterView with enhanced features.
Key Features
- Enhanced RouterView & KeepAlive functionality with support for dynamic parameter route caching
- Precise rendering (ignore parent routes with components) for intuitive nested route handling
Current issues with Vue Router:
- Issue 1: When using
KeepAlive
, cannot precisely control component instance caching for dynamic routes (e.g.,/user/:id
) - Issue 2: Route component
name
must match route configuration'sname
attribute for proper caching
- Issue 1: Official nested routes require either nested
RouterView
or flat route registration, leading to:- Nested RouterView approach: Redundant rendering logic in sub-pages
- Flat registration: Loses
route.matched
convenience and feels unintuitive
This plugin solves these issues through the BetterRouterView
component with a more efficient solution.
npm i vue-router-better-view
import { BetterRouterView } from 'vue-router-better-view'
// Globally register BetterRouterView component
app.use(BetterRouterView)
<!-- layout.vue -->
<script
setup
lang="ts"
>
import { BetterRouterView } from 'vue-router-better-view'
</script>
<template>
<main>
<better-router-view />
</main>
</template>
By default, /user/1
and /user/2
are treated as same component, preventing fine-grained caching control.
Custom cache identifier via resolveViewKey
:
<script
setup
lang="ts"
>
import { BetterRouterView, type ResolveViewKey } from 'vue-router-better-view'
const resolveViewKey: ResolveViewKey = (route) => {
// Cache by path if marked as singleton
if (route.meta.singleton) return route.path
// Cache by fullPath (including params) otherwise
return route.fullPath
}
</script>
<template>
<main>
<better-router-view
v-slot="{ Component }"
:resolve-view-key="resolveViewKey"
>
<!-- Include/exclude based on resolveViewKey value -->
<keep-alive>
<component :is="Component" />
</keep-alive>
</better-router-view>
</main>
</template>
Directly render <UserDetail />
for /system/user/detail
instead of parent component <User />
// src/router/index.ts
const routes: RouteRecordRaw[] = [
{
path: '/system',
component: Layout, // Layout component requiring precise rendering
children: [
{
path: 'user',
component: UserList,
children: [
{
path: 'detail/:id?',
component: UserDetail,
},
],
},
],
},
]
-
Using
<BetterRouterView />
:<script setup lang="ts" > import { BetterRouterView } from 'vue-router-better-view' </script> <template> <main> <!-- Enable precise rendering with 'exact' attribute --> <better-router-view exact /> </main> </template>
-
Using
useExactView
Function:
Must be called in the component containing
<RouterView />
<script
setup
lang="ts"
>
import { useExactView } from 'vue-router-better-view'
useExactView({ exact: true })
</script>
<template>
<main>
<!-- Can use native RouterView component -->
<router-view />
</main>
</template>
interface BetterRouterViewProps extends RouterViewProps {
/**
* Gets view component identifier for current route
* - When unset or returns falsy value, behaves like standard RouterView
* @param route Current route
* @returns View component identifier
*/
resolveViewKey?: ResolveViewKey
/**
* Whether to enable precise route matching
* - boolean: `true` enables precise matching but disallows nested RouterView
* - number: Enables precise matching with nested RouterView support
* - null: Default, restores standard RouterView behavior
* @default null
*/
exact?: boolean | number | null
}
- Fully compatible with standard
<RouterView>
usage - Ensure
exact
attribute is enabled in nested route configurations
Your support fuels continuous improvement! If this project helps you, consider buying me a juice 🍹:
Alipay | |
---|---|
![]() |
![]() |