如何配置vue-router导航守卫验证动态路由课程slug的有效性?
问题根因
你配置的全局通配404路由只会匹配到完全没有命中任何路由规则的路径,/courses/wrong-course已经命中了/courses/:slug的路由规则,所以不会触发全局404跳转。页面卡死是因为Course组件内获取课程数据的请求返回404后,你没有做错误分支的逻辑处理,加载动画的状态没有被关闭,也没有触发404跳转。
解决方案
这里提供两种常用实现思路,你可以根据业务场景选择:
方案1:路由独享守卫校验(推荐)
直接在路由配置层增加校验逻辑,slug合法才放行进入组件,从根源避免无效请求进入组件层:
// router.js 中修改对应路由配置 { path: '/courses/:slug', component: Course, name: 'course', // 新增路由独享守卫 beforeEnter: async (to, from, next) => { const courseSlug = to.params.slug try { // 调用Laravel后端提供的slug校验接口,可提前写一个轻量接口只返回存在状态,不用返回完整课程数据 const checkRes = await fetch(`/api/courses/validate/${courseSlug}`) if (checkRes.ok) { next() } else { // 校验不通过直接跳转到你已配置的404页 next({ name: 'NotFound' }) } } catch (err) { next({ name: 'NotFound' }) } } }
优点:逻辑统一收敛,所有课程路由的合法性校验都在路由层处理,不需要在业务组件内重复写判断逻辑
方案2:组件内请求异常拦截
如果不想额外新增校验接口,可以直接在Course组件的请求逻辑里增加异常分支处理:
// Course.vue 中修改课程数据请求逻辑 async fetchCourseDetail() { this.loading = true try { const res = await this.$axios.get(`/api/courses/${this.$route.params.slug}`) this.courseInfo = res.data } catch (err) { // 捕获到404状态码直接跳转404页 if (err.response?.status === 404) { this.$router.push({ name: 'NotFound' }) } // 其他异常可自行加对应处理逻辑 } finally { // 无论请求成功失败都关闭加载状态,避免页面卡死 this.loading = false } }
优点:不需要额外新增后端接口,可灵活适配组件内的特殊业务处理逻辑
补充说明
如果你的项目用到了Vuex/Pinia,也可以把slug校验的逻辑封装到Store中,两种方案都可以调用Store的方法做校验,逻辑和上面的实现一致。
内容的提问来源于stack exchange,提问作者ElendilTheTall
相关产品推荐
相关产品推荐

