Vue-Router路径存在但无关联记录的404错误处理咨询
处理Vue-Router中路由匹配但数据不存在的404场景
问题场景
路由配置中存在匹配路径(如tutorials/:slug),但请求对应API后返回404状态,需要显示通用404页面,同时保留当前URL不改变。当前实现用router.push('/error-404')会修改URL,不符合需求。
解决方案
方案1:组件内条件渲染(推荐)
在目标页面组件中,根据API请求结果切换渲染内容:数据不存在时直接渲染404组件,无需修改路由。
1. 修改Store的Action
确保正确捕获API的404错误,并更新状态标记:
// src/store/tutorials/action.js const show = (context, data) => { return new Promise((resolve, reject) => { ProfileService.show(data) .then((response) => { // 重置404状态 context.commit('tutorials/setNotFound', false); context.commit('tutorials/setModel', { model: response.tutorial }); resolve(response); }) .catch((error) => { console.log(error); // 根据API返回格式判断是否为404 if (error.response?.status === 404) { context.commit('tutorials/setNotFound', true); } reject(error); }); }); };
同时在store的mutations中添加状态更新方法:
// src/store/tutorials/mutation.js const setNotFound = (state, value) => { state.notFound = value; };
2. 修改Tutorial.vue组件
根据store的notFound状态,切换渲染404组件或正常内容:
<template> <div v-if="!$store.state.tutorials.notFound"> <!-- 正常教程内容区域 --> <h1>{{ tutorial.title }}</h1> <!-- 其他内容结构 --> </div> <ErrorNotFound v-else /> </template> <script setup> import { useRoute, useStore } from 'vue-router'; import ErrorNotFound from './ErrorNotFound.vue'; const route = useRoute(); const store = useStore(); const fetchData = async () => { try { await store.dispatch('tutorials/show', { slug: route.params.slug }); // 数据加载成功后的后续逻辑 } catch (error) { // 无需跳转路由,状态更新后组件自动切换渲染内容 } }; // 页面初始化时触发数据请求 fetchData(); </script>
方案2:全局守卫+路由元信息(多页面复用场景)
如果多个页面都需要处理类似逻辑,可通过全局路由守卫提前校验数据:
1. 更新路由配置
给需要校验的路由添加元信息标记:
// src/routers/routes.js const routes = [ { path: '/', component: () => import('layouts/MainLayout.vue'), children: [ { path: '', component: () => import('pages/IndexPage.vue') }, { name: 'tutorial', path: '/tutorials/:slug', props: true, component: () => import('pages/Tutorial.vue'), meta: { requiresDataCheck: true, dataAction: 'tutorials/show' } } ] }, { path: '/:catchAll(.*)*', component: () => import('pages/ErrorNotFound.vue') } ];
2. 添加全局前置守卫
在路由初始化时添加守卫,提前请求数据并处理错误:
// src/routers/index.js import { createRouter, createWebHistory } from 'vue-router'; import routes from './routes'; import store from '../store'; const router = createRouter({ history: createWebHistory(), routes }); router.beforeEach(async (to, from, next) => { if (to.meta.requiresDataCheck) { try { await store.dispatch(to.meta.dataAction, { slug: to.params.slug }); next(); } catch (error) { if (error.response?.status === 404) { // 不跳转路由,让目标页面自行渲染404 next(); } else { // 其他类型错误的处理逻辑 next(); } } } else { next(); } }); export default router;
后续Tutorial.vue的渲染逻辑与方案1一致,通过store状态切换内容。
关键注意点
- 禁止用
router.push跳转,否则会修改URL,破坏用户当前访问路径 - 根据实际API返回格式调整404错误判断逻辑
- 组件内建议添加加载状态,避免数据请求期间的空白页面
内容的提问来源于stack exchange,提问作者whoacowboy
相关产品推荐
相关产品推荐

