Skip to content

NavigationFailureType 枚举 | Vue Router API

概述

NavigationFailureType 枚举定义了 Vue Router 中导航失败的类型。当导航被阻止或失败时,路由器会返回一个包含失败类型的错误对象。

枚举值

typescript
enum NavigationFailureType {
  cancelled = 2,
  duplicated = 4
}

具体枚举值说明

cancelled - 导航被取消

: 2说明: 导航被导航守卫取消

typescript
// 导航被守卫取消的示例
const result = await router.push('/protected-route')
if (result && result.type === NavigationFailureType.cancelled) {
  console.log('导航被守卫取消')
}

duplicated - 重复导航

: 4说明: 尝试导航到当前所在的路由

typescript
// 重复导航的示例
const result = await router.push(router.currentRoute.value.fullPath)
if (result && result.type === NavigationFailureType.duplicated) {
  console.log('重复导航到当前页面')
}

实际应用场景

场景 1:导航错误处理

javascript
async function safeNavigate(to) {
  try {
    const result = await router.push(to)
    
    if (result) {
      switch (result.type) {
        case NavigationFailureType.cancelled:
          console.warn('导航被取消:', result)
          showToast('导航被阻止,请检查权限')
          break
          
        case NavigationFailureType.duplicated:
          console.log('重复导航,忽略')
          break
          
        default:
          console.error('未知导航错误:', result)
      }
      return false
    }
    
    return true
    
  } catch (error) {
    console.error('导航异常:', error)
    return false
  }
}

场景 2:智能重试机制

javascript
class NavigationService {
  constructor(router) {
    this.router = router
  }
  
  async smartNavigate(to, options = {}) {
    const { maxRetries = 3, retryDelay = 1000 } = options
    
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      const result = await this.router.push(to)
      
      if (!result) {
        // 导航成功
        return { success: true }
      }
      
      // 处理导航失败
      switch (result.type) {
        case NavigationFailureType.cancelled:
          if (attempt < maxRetries) {
            console.log(`导航被取消,${retryDelay}ms后重试...`)
            await this.delay(retryDelay)
            continue
          }
          return { success: false, reason: 'cancelled', result }
          
        case NavigationFailureType.duplicated:
          return { success: true } // 重复导航视为成功
          
        default:
          return { success: false, reason: 'unknown', result }
      }
    }
  }
  
  delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms))
  }
}

场景 3:用户界面反馈

vue
<script setup>
import { NavigationFailureType } from 'vue-router'

const router = useRouter()
const navigationStatus = ref('idle')

async function handleNavigation(to) {
  navigationStatus.value = 'navigating'
  
  const result = await router.push(to)
  
  if (result) {
    switch (result.type) {
      case NavigationFailureType.cancelled:
        navigationStatus.value = 'cancelled'
        showErrorNotification('导航被阻止,请检查权限设置')
        break
        
      case NavigationFailureType.duplicated:
        navigationStatus.value = 'duplicated'
        // 重复导航不需要特殊处理
        break
        
      default:
        navigationStatus.value = 'failed'
        showErrorNotification('导航失败')
    }
  } else {
    navigationStatus.value = 'success'
  }
}
</script>

<template>
  <button 
    @click="handleNavigation('/target')"
    :disabled="navigationStatus === 'navigating'"
  >
    <span v-if="navigationStatus === 'navigating'">导航中...</span>
    <span v-else>前往目标页面</span>
  </button>
</template>

高级用法

自定义导航错误处理

javascript
// 扩展导航错误类型
class ExtendedNavigationError extends Error {
  constructor(failure, customMessage) {
    super(customMessage)
    this.failure = failure
    this.name = 'ExtendedNavigationError'
  }
}

// 包装导航函数
function createExtendedNavigation(router) {
  return async function extendedNavigate(to) {
    const result = await router.push(to)
    
    if (result) {
      switch (result.type) {
        case NavigationFailureType.cancelled:
          throw new ExtendedNavigationError(
            result, 
            '导航被守卫阻止,请检查访问权限'
          )
          
        case NavigationFailureType.duplicated:
          // 可以记录重复导航日志
          console.warn('检测到重复导航:', to)
          return { success: true, duplicated: true }
          
        default:
          throw new ExtendedNavigationError(result, '未知导航错误')
      }
    }
    
    return { success: true }
  }
}

导航分析统计

javascript
// 导航分析工具
class NavigationAnalytics {
  constructor(router) {
    this.router = router
    this.setupTracking()
  }
  
  setupTracking() {
    // 监听所有导航操作
    this.router.afterEach((to, from, failure) => {
      this.trackNavigation(to, from, failure)
    })
  }
  
  trackNavigation(to, from, failure) {
    const event = {
      timestamp: Date.now(),
      from: from.path,
      to: to.path,
      success: !failure,
      failureType: failure?.type
    }
    
    // 发送到分析平台
    analytics.track('navigation', event)
    
    // 记录失败统计
    if (failure) {
      this.recordFailure(failure.type)
    }
  }
  
  recordFailure(failureType) {
    const stats = this.getFailureStats()
    
    switch (failureType) {
      case NavigationFailureType.cancelled:
        stats.cancelled++
        break
      case NavigationFailureType.duplicated:
        stats.duplicated++
        break
    }
    
    this.saveFailureStats(stats)
  }
}

最佳实践

1. 统一的错误处理模式

javascript
// 导航错误处理工具
function createNavigationHandler(router) {
  return {
    async navigate(to, options = {}) {
      const { 
        onSuccess, 
        onCancelled, 
        onDuplicated, 
        onError 
      } = options
      
      try {
        const result = await router.push(to)
        
        if (result) {
          switch (result.type) {
            case NavigationFailureType.cancelled:
              onCancelled?.(result)
              return { success: false, type: 'cancelled' }
              
            case NavigationFailureType.duplicated:
              onDuplicated?.(result)
              return { success: true, type: 'duplicated' }
              
            default:
              onError?.(result)
              return { success: false, type: 'unknown' }
          }
        }
        
        onSuccess?.(to)
        return { success: true, type: 'success' }
        
      } catch (error) {
        onError?.(error)
        return { success: false, type: 'exception', error }
      }
    }
  }
}

2. 类型安全处理(TypeScript)

typescript
// 类型安全的导航结果处理
interface NavigationResult {
  success: boolean
  type: 'success' | 'cancelled' | 'duplicated' | 'unknown' | 'exception'
  error?: any
}

function handleNavigationResult(result: any): NavigationResult {
  if (!result) {
    return { success: true, type: 'success' }
  }
  
  switch (result.type) {
    case NavigationFailureType.cancelled:
      return { success: false, type: 'cancelled', error: result }
      
    case NavigationFailureType.duplicated:
      return { success: true, type: 'duplicated' }
      
    default:
      return { success: false, type: 'unknown', error: result }
  }
}

注意事项

  1. 错误对象结构 - 导航失败返回的对象包含 type 属性
  2. 异步处理 - 导航操作是异步的,需要正确处理 Promise
  3. 用户反馈 - 为不同的失败类型提供适当的用户反馈
  4. 日志记录 - 记录导航失败有助于调试和监控

兼容性

  • Vue Router 4.0+
  • TypeScript 支持
  • 所有现代浏览器

🔍 提示:理解导航失败类型有助于构建更健壮的导航系统,提供更好的用户体验和错误处理。

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