路由错误处理改进
路由错误处理改进
Vue.js 应用中路由错误处理是提升用户体验的关键环节。传统方式可能仅依赖 router.onError
捕获导航错误,但现代 Vue Router 提供了更精细的控制手段。下面从错误分类到具体实现方案逐步展开。
错误类型分类
路由错误主要分为三类:
- 导航守卫拒绝:通过
next(false)
或next(new Error())
主动中断 - 组件加载失败:异步路由组件加载时网络错误
- 无效路由匹配:访问未定义的路由路径
// 导航守卫示例
router.beforeEach((to, from, next) => {
if (!userAuthenticated && to.meta.requiresAuth) {
next({ name: 'login' }) // 重定向
// 或 next(false) // 中止导航
} else {
next()
}
})
全局错误捕获方案
基础错误捕获
// 全局错误处理器
router.onError((error) => {
console.error('路由错误:', error)
// 可跳转到统一错误页面
if (isNavigationFailure(error, NavigationFailureType.redirected)) {
showToast('导航被重定向')
}
})
增强型错误处理
结合 Vue 的 errorCaptured 生命周期:
// 在根组件中
export default {
errorCaptured(err, vm, info) {
if (err instanceof NavigationFailure) {
this.$store.commit('ADD_ROUTE_ERROR', err)
return false // 阻止错误继续向上传播
}
}
}
异步组件加载优化
处理动态导入失败情况:
const UserDetails = () => ({
component: import('./UserDetails.vue'),
loading: LoadingComponent,
error: ErrorComponent,
delay: 200,
timeout: 3000
})
// 或使用新的 defineAsyncComponent
const AsyncComp = defineAsyncComponent({
loader: () => import('./Article.vue'),
onError(error, retry, fail) {
if (error.message.includes('timeout')) {
retry()
} else {
fail()
}
}
})
404 路由处理实践
实现智能 404 页面:
const routes = [
// ...其他路由
{
path: '/:pathMatch(.*)*',
component: NotFound,
beforeEnter(to) {
// 分析路径尝试智能重定向
const possibleRedirect = analyzePath(to.params.pathMatch)
if (possibleRedirect) {
return possibleRedirect
}
}
}
]
错误状态管理
将路由错误纳入 Vuex/Pinia 统一管理:
// Pinia store示例
export const useErrorStore = defineStore('errors', {
state: () => ({
routeErrors: [],
lastError: null
}),
actions: {
addRouteError(error) {
this.routeErrors.push({
error,
timestamp: new Date(),
route: router.currentRoute.value
})
this.lastError = error
}
}
})
// 在路由守卫中使用
router.onError((error) => {
useErrorStore().addRouteError(error)
})
开发环境增强调试
利用 Vue Devtools 扩展路由调试能力:
if (process.env.NODE_ENV === 'development') {
router.afterEach((to, from, failure) => {
if (failure) {
console.group('[路由错误]')
console.log('失败类型:', failure.type)
console.log('目标路由:', to)
console.log('来源路由:', from)
console.groupEnd()
}
})
}
用户反馈设计
错误发生时提供友好交互:
<template>
<div v-if="routeError">
<h3>页面加载失败</h3>
<p>{{ errorMessage }}</p>
<button @click="retry">重试</button>
<button @click="report">反馈问题</button>
</div>
</template>
<script>
export default {
data() {
return {
routeError: null
}
},
computed: {
errorMessage() {
if (!this.routeError) return ''
return this.routeError.isNetworkError
? '网络连接异常'
: '页面资源加载失败'
}
},
methods: {
retry() {
this.$router.go()
},
report() {
// 发送错误报告
}
}
}
</script>
性能监控集成
将路由错误接入性能监控系统:
import { trackError } from './monitoring'
router.onError((error) => {
trackError({
type: 'ROUTE_FAILURE',
error,
route: router.currentRoute.value,
timing: performance.now() - navigationStartTime
})
})
router.beforeEach(() => {
navigationStartTime = performance.now()
})
测试策略建议
编写路由错误测试用例:
import { mount } from '@vue/test-utils'
describe('路由错误处理', () => {
it('应显示404页面当访问无效路由', async () => {
const wrapper = mount(App, {
global: {
plugins: [router]
}
})
await router.push('/invalid-route')
expect(wrapper.findComponent(NotFound).exists()).toBe(true)
})
it('应捕获异步组件加载错误', async () => {
jest.spyOn(console, 'error').mockImplementation(() => {})
const error = new Error('加载失败')
importMock.mockRejectedValueOnce(error)
await router.push('/async-route')
await flushPromises()
expect(wrapper.findComponent(ErrorComponent).exists()).toBe(true)
})
})
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:路由过渡动画变化
下一篇:路由与Pinia集成