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

Vue Router如何让全局catch-all路由也能捕获与定义路由部分匹配的无效URL

原因说明

这是Vue Router的默认匹配逻辑导致的:路由匹配会按定义顺序优先命中第一个符合规则的路由,/album/foo完全匹配/album/:album的路径规则,所以会直接进入Album组件,不会走到后续的catch-all路由。


方案1:路由独享守卫提前校验(通用度最高,适合所有场景)

直接在Album路由的配置中增加beforeEnter守卫,进入路由前先向Sanity发起查询校验对应相册是否存在,不存在则直接跳转404,无需挂载Album组件再做判断。

// 封装校验相册是否存在的公共方法
const validateAlbumExist = async (albumSlug) => {
  // 替换为你自己的Sanity查询逻辑
  const album = await sanityClient.fetch(`*[_type == "album" && slug.current == $slug][0]`, { slug: albumSlug })
  return !!album
}

const routes = [
  {
    path: '/album/:album',
    name: 'album',
    component: Album,
    beforeEnter: async (to, from, next) => {
      const isAlbumExist = await validateAlbumExist(to.params.album)
      if (isAlbumExist) {
        next()
      } else {
        // 不存在则直接跳转至404路由
        next({ name: 'NotFound' })
      }
    }
  },
  {
    path: '/',
    name: 'home',
    component: Home,
  },
  // 注意Vue Router 4的catch-all路由需要用该写法,原有/*写法已废弃
  {
    path: '/:pathMatch(.*)*',
    name: 'NotFound',
    component: NotFound,
  },
];

方案2:路由参数加正则约束(性能最优,适合相册命名有固定规则的场景)

如果你的相册slug有统一的格式规则,比如都是6位十六进制字符、纯数字ID等,可以直接在路由定义时给参数加上正则匹配规则,不符合规则的请求不会命中Album路由,自动走catch-all的404。
示例(相册slug为6位十六进制字符的场景):

{
  path: '/album/:album([a-f0-9]{6})',
  name: 'album',
  component: Album,
}

方案3:预注册所有合法相册路由(适合静态站点/SSG场景)

如果你的站点是静态生成、相册数量少且更新频率低,可以在应用初始化/构建阶段从Sanity拉取所有合法的相册slug,动态注册对应的路由,未注册的/album/xxx路径会直接命中404。

// 应用初始化时拉取所有合法相册slug
const albumSlugs = await sanityClient.fetch(`*[_type == "album"].slug.current`)
// 逐个注册合法的相册路由
albumSlugs.forEach(slug => {
  router.addRoute({
    path: `/album/${slug}`,
    name: `album-${slug}`,
    component: Album
  })
})
// 最后注册catch-all路由
router.addRoute({
  path: '/:pathMatch(.*)*',
  component: NotFound
})

内容的提问来源于stack exchange,提问作者Kevin Britten

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 11:48:02