You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 19:22:26