RouteLocationNormalized - 标准化路由位置接口
RouteLocationNormalized 接口定义了经过标准化处理的路由位置信息,它包含了路由匹配和解析后的完整数据,用于导航过程中的路由位置表示。📊
📋 接口定义
typescript
interface RouteLocationNormalized extends RouteLocationBase {
// 继承 RouteLocationBase 的所有属性
// 并确保这些属性已经过标准化处理
}🎯 功能说明
这个接口表示路由位置已经完成了标准化处理,具有以下特点:
- 数据标准化 - 所有属性都经过统一格式处理
- 路径解析完成 - 动态参数和查询参数已正确解析
- 匹配信息完整 - 路由匹配记录已经生成
- 导航过程使用 - 主要用于导航守卫和路由解析过程
🔧 属性详解
继承了 RouteLocationBase 的所有属性,并确保这些属性都是标准化格式。
核心属性回顾
| 属性 | 类型 | 说明 |
|---|---|---|
path | string | 标准化后的路径部分 |
params | RouteParams | 解析后的路径参数对象 |
query | LocationQuery | 解析后的查询参数对象 |
hash | string | 标准化后的哈希部分 |
fullPath | string | 完整的标准化路径 |
matched | RouteRecordNormalized[] | 标准化后的匹配路由记录 |
meta | RouteMeta | 合并后的路由元数据 |
redirectedFrom | RouteLocation | undefined | 标准化后的重定向来源 |
💡 实际应用示例
在导航守卫中使用
javascript
// 全局前置守卫
router.beforeEach((to, from) => {
// to 和 from 都是 RouteLocationNormalized 类型
console.log('从:', from.path, '导航到:', to.path)
// 检查权限
if (to.meta.requiresAuth && !isAuthenticated()) {
// 重定向到登录页
return '/login'
}
// 允许导航继续
return true
})路由解析守卫
javascript
// 全局解析守卫
router.beforeResolve(async (to, from) => {
// 在所有组件内守卫和异步路由组件解析之后调用
// to 此时已经是完整的标准化路由位置
// 预加载数据
if (to.meta.requiresData) {
await preloadRouteData(to)
}
// 设置页面标题
if (to.meta.title) {
document.title = to.meta.title
}
})自定义路由处理逻辑
javascript
// 创建路由处理中间件
function createRouteMiddleware(handler) {
return (to: RouteLocationNormalized, from: RouteLocationNormalized) => {
// 在导航过程中处理路由信息
return handler(to, from)
}
}
// 使用示例:日志记录中间件
const loggingMiddleware = createRouteMiddleware((to, from) => {
console.log(`路由变化: ${from.path} → ${to.path}`)
console.log('参数:', to.params)
console.log('查询:', to.query)
return true
})
// 注册到路由守卫
router.beforeEach(loggingMiddleware)🎯 与 RouteLocationNormalizedLoaded 的区别
使用时机不同
javascript
// RouteLocationNormalized - 导航过程中
router.beforeEach((to, from) => {
// to 是 RouteLocationNormalized
// 此时导航尚未完成,组件可能还未加载
})
// RouteLocationNormalizedLoaded - 导航完成后
const route = useRoute() // RouteLocationNormalizedLoaded
// 此时导航已完成,组件已加载数据完整性
javascript
// 在导航守卫中(RouteLocationNormalized)
router.beforeEach((to, from) => {
// to.matched 可能包含部分匹配信息
// 异步组件可能还未解析完成
})
// 在组件中(RouteLocationNormalizedLoaded)
const route = useRoute()
// route.matched 包含完整的匹配信息
// 所有异步组件都已解析完成🔧 实用工具函数
路由位置比较
typescript
// 比较两个路由位置是否相同(忽略哈希)
function areRoutesEqualIgnoringHash(
a: RouteLocationNormalized,
b: RouteLocationNormalized
): boolean {
return a.path === b.path &&
JSON.stringify(a.params) === JSON.stringify(b.params) &&
JSON.stringify(a.query) === JSON.stringify(b.query)
}
// 检查是否是同一路由的不同参数
function isSameRouteWithDifferentParams(
a: RouteLocationNormalized,
b: RouteLocationNormalized
): boolean {
return a.path === b.path &&
a.name === b.name &&
JSON.stringify(a.query) === JSON.stringify(b.query) &&
// 只有参数不同
JSON.stringify(a.params) !== JSON.stringify(b.params)
}路由信息提取
typescript
// 提取路由的关键信息用于缓存或日志
function extractRouteKeyInfo(route: RouteLocationNormalized) {
return {
path: route.path,
name: route.name,
params: route.params,
query: route.query,
meta: route.meta
}
}
// 创建路由的指纹(用于去重或比较)
function createRouteFingerprint(route: RouteLocationNormalized): string {
return JSON.stringify({
path: route.path,
params: route.params,
query: route.query
})
}路由转换工具
typescript
// 将路由位置转换为导航参数
function toNavigationParams(route: RouteLocationNormalized) {
return {
path: route.path,
query: route.query,
params: route.params,
hash: route.hash
}
}
// 从路由位置创建新的导航目标
function createRedirectTarget(
route: RouteLocationNormalized,
modifications: Partial<RouteLocationNormalized>
) {
return {
path: modifications.path || route.path,
query: { ...route.query, ...modifications.query },
params: { ...route.params, ...modifications.params },
hash: modifications.hash || route.hash
}
}🎯 高级应用场景
动态权限控制系统
javascript
// 基于路由元数据的动态权限检查
async function checkRoutePermissions(
to: RouteLocationNormalized
): Promise<boolean> {
const requiredPermissions = to.meta.requiredPermissions || []
if (requiredPermissions.length === 0) {
return true // 无需权限
}
// 检查用户是否拥有所有所需权限
const userPermissions = await getUserPermissions()
return requiredPermissions.every(perm =>
userPermissions.includes(perm)
)
}
// 在导航守卫中使用
router.beforeEach(async (to, from) => {
const hasPermission = await checkRoutePermissions(to)
if (!hasPermission) {
return '/unauthorized'
}
return true
})A/B 测试路由系统
javascript
// 基于路由的 A/B 测试
function getVariantForRoute(route: RouteLocationNormalized): string {
const routeKey = `${route.path}-${route.name || ''}`
const variant = abTestManager.getVariant(routeKey)
return variant || 'A' // 默认变体 A
}
// 在导航守卫中设置变体信息
router.beforeEach((to, from) => {
const variant = getVariantForRoute(to)
// 将变体信息添加到路由元数据
to.meta.abTestVariant = variant
// 根据变体决定是否重定向
if (variant === 'B' && to.meta.hasVariantB) {
return to.meta.variantBPath
}
return true
})路由级数据预加载
javascript
// 路由数据预加载系统
const routeDataCache = new Map()
async function preloadRouteData(route: RouteLocationNormalized) {
const cacheKey = route.fullPath
// 检查缓存
if (routeDataCache.has(cacheKey)) {
return routeDataCache.get(cacheKey)
}
// 根据路由元数据决定预加载策略
const preloadConfig = route.meta.preload || {}
const data = await loadRequiredData(route, preloadConfig)
// 缓存结果
routeDataCache.set(cacheKey, data)
return data
}
// 在解析守卫中使用
router.beforeResolve(async (to, from) => {
if (to.meta.requiresData) {
await preloadRouteData(to)
}
})🔗 相关接口
RouteLocationBase- 基础路由位置接口RouteLocationNormalizedLoaded- 已加载的路由位置RouteRecordNormalized- 标准化路由记录
💡 专业建议:在导航守卫中处理
RouteLocationNormalized时,注意异步操作的正确处理,确保返回适当的 Promise 或使用 async/await 语法。