matchedRouteKey - 匹配路由键
matchedRouteKey 是一个Symbol类型的常量,用于在 Vue 的依赖注入系统中标识当前匹配的路由记录。它是 Vue Router 内部使用的注入键之一。🔑
📋 变量定义
typescript
const matchedRouteKey: InjectionKey<RouteRecordNormalized>🎯 功能说明
这个变量提供了对当前匹配的路由记录的访问能力:
- 依赖注入键 - 用于在组件树中注入当前路由记录
- 类型安全 - 提供完整的 TypeScript 类型支持
- 内部使用 - 主要用于 Vue Router 内部组件和高级用法
🔧 技术细节
类型定义
typescript
// matchedRouteKey 的完整类型
const matchedRouteKey: InjectionKey<RouteRecordNormalized>
// 对应的注入值类型
interface RouteRecordNormalized {
path: string
meta: RouteMeta
name?: RouteRecordName
components: Record<string, Component>
// ... 其他字段
}在 Vue Router 中的使用
typescript
// Vue Router 内部使用示例
export default defineComponent({
inject: {
matchedRoute: { from: matchedRouteKey }
},
setup(props, { injections }) {
const route = injections.matchedRoute as RouteRecordNormalized
// 使用匹配的路由记录
}
})💡 实际应用示例
在自定义组件中访问匹配路由
vue
<script setup>
import { matchedRouteKey } from 'vue-router'
import { inject } from 'vue'
// 注入当前匹配的路由记录
const matchedRoute = inject(matchedRouteKey)
// 使用匹配的路由信息
const routeMeta = computed(() => matchedRoute?.meta || {})
const routeComponents = computed(() => matchedRoute?.components || {})
</script>
<template>
<div>
<h3>当前匹配的路由信息</h3>
<p>路径: {{ matchedRoute?.path }}</p>
<p>名称: {{ matchedRoute?.name }}</p>
<pre>{{ routeMeta }}</pre>
</div>
</template>高级路由信息组件
vue
<script setup>
import { matchedRouteKey, routeLocationKey } from 'vue-router'
import { inject, computed } from 'vue'
const matchedRoute = inject(matchedRouteKey)
const routeLocation = inject(routeLocationKey)
// 计算完整的路由信息
const routeInfo = computed(() => ({
currentPath: routeLocation?.path,
matchedPath: matchedRoute?.path,
routeName: matchedRoute?.name,
meta: matchedRoute?.meta,
params: routeLocation?.params,
query: routeLocation?.query
}))
// 检查是否为活动路由
const isActiveRoute = computed(() => {
return matchedRoute?.path === routeLocation?.path
})
</script>
<template>
<div :class="{ 'active-route': isActiveRoute }">
<h4>路由调试信息</h4>
<pre>{{ routeInfo }}</pre>
</div>
</template>路由感知的布局组件
vue
<script setup>
import { matchedRouteKey } from 'vue-router'
import { inject, computed } from 'vue'
const matchedRoute = inject(matchedRouteKey)
// 根据路由元数据动态调整布局
const layoutConfig = computed(() => {
const meta = matchedRoute?.meta || {}
return {
showSidebar: meta.showSidebar !== false,
sidebarWidth: meta.sidebarWidth || 250,
theme: meta.theme || 'light',
maxWidth: meta.maxWidth || '1200px'
}
})
// 检查是否需要特殊处理
const requiresSpecialHandling = computed(() => {
return matchedRoute?.meta?.specialFeature === true
})
</script>
<template>
<div
class="layout"
:class="`theme-${layoutConfig.theme}`"
:style="{ maxWidth: layoutConfig.maxWidth }"
>
<aside v-if="layoutConfig.showSidebar" :style="{ width: `${layoutConfig.sidebarWidth}px` }">
<slot name="sidebar" />
</aside>
<main :class="{ 'with-sidebar': layoutConfig.showSidebar }">
<slot />
<SpecialFeature v-if="requiresSpecialHandling" />
</main>
</div>
</template>🎯 使用场景
路由感知的导航组件
vue
<script setup>
import { matchedRouteKey } from 'vue-router'
import { inject, computed } from 'vue'
const matchedRoute = inject(matchedRouteKey)
// 生成基于当前路由的面包屑导航
const breadcrumbs = computed(() => {
if (!matchedRoute) return []
return matchedRoute.matched.map(route => ({
name: route.name || route.path,
path: route.path,
meta: route.meta
}))
})
</script>
<template>
<nav class="breadcrumb">
<router-link
v-for="crumb in breadcrumbs"
:key="crumb.path"
:to="crumb.path"
class="breadcrumb-item"
>
{{ crumb.meta?.title || crumb.name }}
</router-link>
</nav>
</template>权限检查组件
vue
<script setup>
import { matchedRouteKey } from 'vue-router'
import { inject, computed } from 'vue'
const matchedRoute = inject(matchedRouteKey)
const user = useUserStore()
// 检查当前路由的权限要求
const hasRequiredPermissions = computed(() => {
const requiredPermissions = matchedRoute?.meta?.permissions || []
if (requiredPermissions.length === 0) return true
return requiredPermissions.every(perm =>
user.permissions.includes(perm)
)
})
// 检查角色要求
const hasRequiredRole = computed(() => {
const requiredRole = matchedRoute?.meta?.requiredRole
if (!requiredRole) return true
return user.role === requiredRole
})
</script>
<template>
<div v-if="hasRequiredPermissions && hasRequiredRole">
<slot />
</div>
<div v-else class="access-denied">
<h3>访问被拒绝</h3>
<p>您没有访问此页面的权限。</p>
</div>
</template>🔧 实用工具函数
路由信息工具
typescript
// 获取当前匹配路由的详细信息
export function useMatchedRoute() {
const matchedRoute = inject(matchedRouteKey)
return {
// 基础信息
path: matchedRoute?.path,
name: matchedRoute?.name,
meta: matchedRoute?.meta || {},
// 组件信息
components: matchedRoute?.components || {},
hasNamedComponents: Object.keys(matchedRoute?.components || {}).length > 0,
// 验证函数
hasMeta: (key: string) => key in (matchedRoute?.meta || {}),
getMeta: (key: string) => matchedRoute?.meta?.[key]
}
}
// 使用示例
const { meta, hasMeta, getMeta } = useMatchedRoute()路由匹配检查
typescript
// 检查当前路由是否匹配特定模式
export function useRouteMatch() {
const matchedRoute = inject(matchedRouteKey)
const route = useRoute()
return {
// 精确匹配检查
isExactMatch: computed(() =>
matchedRoute?.path === route.path
),
// 模式匹配检查
matchesPattern: (pattern: RegExp) =>
pattern.test(matchedRoute?.path || ''),
// 参数匹配检查
hasParam: (param: string) =>
param in (route.params || {})
}
}🔗 相关变量
routeLocationKey- 路由位置注入键routerKey- 路由实例注入键routerViewLocationKey- 路由视图位置键
💡 专业建议:
matchedRouteKey主要用于高级场景和自定义路由组件开发。在大多数情况下,使用useRoute()组合式 API 是更简单和推荐的方式。