如何在Nuxt中实现类似WordPress的动态URL自定义重写功能
完全可以实现,核心通过路由中间件或者服务端重写规则就能搞定,不需要改你现有的业务请求逻辑,具体实现方式如下:
方案1:全版本通用的路由中间件方案
这个方案兼容Nuxt2、Nuxt3所有版本,灵活性最高:
步骤1:调整动态路由命名
把原有pages/tools/_id.vue、pages/material/_id.vue重命名为pages/tools/_slug.vue、pages/material/_slug.vue,这样Nuxt会自动匹配/tools/任意字符、/material/任意字符格式的路径,将路径后缀作为slug参数传入页面。
步骤2:新增路由映射中间件
新增路由中间件文件(Nuxt2路径为~/middleware/rewrite-slug.js,Nuxt3为~/middleware/rewrite-slug.global.js自动全局生效),核心逻辑如下:
export default function ({ route, params, error }) { // 匹配tools、material分类的动态路径 const type = route.path.split('/')[1] if (['tools', 'material'].includes(type) && params.slug) { // 调用后端接口,传slug和分类查询对应资源ID // 你可以根据自己的项目调整接口请求方式,也可以加本地缓存避免重复请求 return $axios.get('/api/get-id-by-slug', { params: { slug: params.slug, type: type } }).then(res => { if (res.data.id) { // 将查询到的ID挂载到路由参数上,原有页面按之前的逻辑拿ID请求内容即可,不需要修改 params.id = res.data.id } else { // 没有匹配到资源直接返回404 return error({ statusCode: 404, message: '资源不存在' }) } }) } }
可选优化:旧ID路径301跳转
如果要避免原来的/tools/1格式路径产生重复内容影响SEO,可以在中间件加判断:如果slug是纯数字格式,就调用接口查询对应的slug,做301重定向到新的slug路径即可。
方案2:Nuxt3专属服务端重写方案
如果你用的是Nuxt3,不需要修改任何页面文件,直接在nuxt.config.ts中配置nitro的动态重写规则即可,所有映射在服务端完成,性能更高:
export default defineNuxtConfig({ nitro: { async rewrite(request) { const url = new URL(request.url) // 匹配tools分类路径 const toolMatch = url.pathname.match(/^\/tools\/([^\/]+)$/) if (toolMatch) { const slug = toolMatch[1] const id = await $fetch('/api/get-id-by-slug', { query: { slug, type: 'tools' } }) if (id) return `/tools/${id}` } // 匹配material分类路径 const materialMatch = url.pathname.match(/^\/material\/([^\/]+)$/) if (materialMatch) { const slug = materialMatch[1] const id = await $fetch('/api/get-id-by-slug', { query: { slug, type: 'material' } }) if (id) return `/material/${id}` } } } })
这个方案下你原来的_id.vue页面完全不需要修改,所有slug到ID的转换都在服务端隐式完成,用户看到的始终是自定义slug的路径,页面还是按原来的逻辑拿ID请求内容即可。
内容的提问来源于stack exchange,提问作者Michel Gisenaël
相关产品推荐
相关产品推荐

