Vue 路由错误处理实战指南

在 Vue 应用开发中,优雅地处理路由错误是提升用户体验的重要环节。本文将深入探讨 Vue Router 的错误处理机制,包括 404 页面匹配、错误重定向和导航失败捕获。

一、404 路由匹配规则

基础实现

在 Vue Router 中,可以通过通配符路由 * 来捕获所有未匹配的路由路径:

const routes = [
  // ...其他路由
  {
    path: '/:pathMatch(.*)*',
    name: 'NotFound',
    component: NotFound
  }
]

高级匹配模式

Vue Router 4.x 提供了更灵活的匹配语法:

{
  path: '/:pathMatch(.*)*', // 会匹配任意路径并将参数拆分成数组
  component: NotFound
}

/:pathMatch(.*) 的区别:

  • /:pathMatch(.*) - 匹配并将整个路径作为字符串参数
  • /:pathMatch(.*)* - 匹配并将路径拆分为数组

实践建议

  1. 将 404 路由放在最后:路由匹配是按顺序进行的
  2. 服务端配合:确保服务端也配置了相应的 404 回退路由
  3. 用户友好设计:404 页面应提供返回首页或常用页面的链接

二、错误页面重定向

基本重定向

{
  path: '/old-path',
  redirect: '/new-path'
}

条件重定向

{
  path: '/user/:id',
  redirect: to => {
    // 检查ID是否有效
    if (!isValidId(to.params.id)) {
      return '/invalid-user'
    }
    // 否则继续原导航
    return { ...to, replace: true }
  }
}

命名路由重定向

{
  path: '/legacy-route',
  redirect: { name: 'new-route' }
}

实践建议

  1. 使用 301/302 状态码:对于永久移动的资源,服务端应返回 301
  2. 避免重定向链:多次重定向会影响性能
  3. 保留原始路径信息:可通过路由参数传递原始路径用于分析

三、导航失败捕获

全局错误处理

Vue Router 4 提供了 onError 方法捕获导航错误:

router.onError((error, to, from) => {
  console.error('Navigation error:', error)
  // 可以跳转到错误页面
  if (isNavigationFailure(error, NavigationFailureType.duplicated)) {
    // 忽略重复导航错误
    return
  }
  router.push('/error-page')
})

常见导航错误类型

import { NavigationFailureType, isNavigationFailure } from 'vue-router'

router.beforeEach((to, from, next) => {
  if (to.path === '/restricted') {
    // 传递错误给 onError
    next(new Error('Access denied'))
  } else {
    next()
  }
})

router.onError(error => {
  if (isNavigationFailure(error, NavigationFailureType.aborted)) {
    console.log('Navigation was aborted')
  } else if (isNavigationFailure(error, NavigationFailureType.cancelled)) {
    console.log('Navigation was cancelled')
  } else if (isNavigationFailure(error, NavigationFailureType.duplicated)) {
    console.log('Navigation was duplicated')
  }
})

实践建议

  1. 错误分类处理:区分可忽略错误(如重复导航)和关键错误
  2. 用户反馈:重要的导航错误应反馈给用户,而不仅是控制台记录
  3. 错误日志:将客户端路由错误上报到服务端用于分析

四、综合示例

import { createRouter, createWebHistory } from 'vue-router'
import { NavigationFailureType, isNavigationFailure } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/',
      component: Home
    },
    {
      path: '/product/:id',
      component: Product,
      beforeEnter: (to, from, next) => {
        if (!isValidProductId(to.params.id)) {
          // 重定向到404
          next({ name: 'NotFound', params: { pathMatch: [to.path] } })
        } else {
          next()
        }
      }
    },
    {
      path: '/:pathMatch(.*)*',
      name: 'NotFound',
      component: NotFound
    }
  ]
})

// 全局错误处理
router.onError((error) => {
  if (isNavigationFailure(error, NavigationFailureType.duplicated)) {
    return
  }
  
  // 发送错误到监控系统
  trackError(error)
  
  // 跳转到错误页面
  router.push('/error').catch(() => {})
})

export default router

五、最佳实践总结

  1. 分层处理

    • 路由层面:处理 404 和基本重定向
    • 全局层面:捕获和处理导航错误
    • 组件层面:处理特定路由的错误状态
  2. 性能考虑

    • 懒加载错误页面组件
    • 避免在错误处理中添加复杂逻辑
  3. 用户体验

    • 保持错误页面的品牌一致性
    • 提供有用的导航选项
    • 考虑添加联系支持的方式
  4. 开发体验

    • 在开发环境显示详细错误信息
    • 生产环境使用友好错误页面

通过合理配置路由错误处理,可以显著提升应用的健壮性和用户体验。记住,好的错误处理不是隐藏问题,而是优雅地解决问题。

评论已关闭