Skip to content

matchedRouteKey - 匹配路由键

matchedRouteKey 是一个Symbol类型的常量,用于在 Vue 的依赖注入系统中标识当前匹配的路由记录。它是 Vue Router 内部使用的注入键之一。🔑

📋 变量定义

typescript
const matchedRouteKey: InjectionKey<RouteRecordNormalized>

🎯 功能说明

这个变量提供了对当前匹配的路由记录的访问能力:

  1. 依赖注入键 - 用于在组件树中注入当前路由记录
  2. 类型安全 - 提供完整的 TypeScript 类型支持
  3. 内部使用 - 主要用于 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 || {})
  }
}

🔗 相关变量

💡 专业建议matchedRouteKey 主要用于高级场景和自定义路由组件开发。在大多数情况下,使用 useRoute() 组合式 API 是更简单和推荐的方式。

🚀 Vue Router - 让前端路由变得简单而强大 | 构建现代化单页应用的最佳选择