我有一个Nuxt3项目,我想基于API调用向数据库添加新的路由。例如,假设用户导航到/my-product-1
。路由中间件将查看数据库,如果它找到一个条目,它将返回应该呈现product
页面(而不是类别页面,例如)。
这是我想到的
export default defineNuxtPlugin(() => {
const router = useRouter()
addRouteMiddleware('routing', async (to) => {
if (to.path == '/my-awesome-product') {
router.addRoute({
component: () => import('/pages/product.vue'),
name: to.path,
path: to.path
})
console.log(router.hasRoute(to.path)) // returns TRUE
}
}, { global: true })
})
为了简单起见,我从这个例子中排除了API调用。上面的解决方案可以工作,但在路由的初始加载时不行。路由确实被添加到了Vue路由器中(即使是在第一次访问时),但是,当我直接访问该路由时,它显示了404,只有当我没有在客户端上重新加载页面时,它才会在第二次导航到它时显示正确的页面。
我猜这和路由器没有更新有关...我在GitHub的一个问题中发现了下面的例子,但是,我不能让它在Nuxt3中工作,因为(据我所知)它没有提供next()
方法。当我试图在router.addRoute
行下面添加router.replace(to.path)
时,我陷入了一个无限重定向循环。
// from https://github.com/vuejs/vue-router/issues/3660
// You need to trigger a redirect to resolve again so it includes the newly added
route:
let hasAdded = false;
router.beforeEach((to, from, next) => {
if (!hasAdded && to.path === "/route3") {
router.addRoute(
{
path: "/route3",
name: "route3",
component: () => import("@/views/Route3.vue")
}
);
hasAdded = true;
next('/route3');
return;
}
next();
});
请问我如何解决此问题?
编辑:根据一个建议,我尝试使用navigateTo()
来替换Vue Router中的next()
方法,但是,这在第一次导航到路线时也不起作用。
let dynamicPages: { path: string, type: string }[] = []
export default defineNuxtRouteMiddleware((to, _from) => {
const router = useRouter()
router.addRoute({
path: to.path,
name: to.path,
component: () => import ('/pages/[[dynamic]]/product.vue')
})
if (!dynamicPages.some(route => route.path === to.path)) {
dynamicPages.push({
path: to.path,
type: 'product'
})
return navigateTo(to.fullPath)
}
})
我也想出了这个代码(它的工作方式就像我想要的),但是,我不知道这是否是最好的解决方案。
export default defineNuxtPlugin(() => {
const router = useRouter()
let routes = []
router.beforeEach(async (to, _from, next) => {
const pageType = await getPageType(to.path) // api call
if (isDynamicPage(pageType)) {
router.addRoute({
path: to.path,
name: to.path,
component: () => import(`/pages/[[dynamic]]/product.vue`),
})
if (!routes.some(route => route.path === to.path)) {
routes.push({
path: to.path,
type: pageType,
})
next(to.fullPath)
return
}
}
next()
})
})
2条答案
按热度按时间5f0d552i1#
我建议您在
/page
目录结构中使用动态路由-https://nuxt.com/docs/guide/directory-structure/pages#dynamic-routes[slug]的概念完全是为你的使用情况设计的。你不需要事先知道所有可能的路径。你只需要提供一个占位符,Nuxt就会在运行时负责解析。
k0pti3hp2#
如果您坚持在每次路由更改之前解析调用的方法,那么您正在寻找的用于
next()
方法的Nuxt替代方法是navigateTo
https://nuxt.com/docs/api/utils/navigate-to我建议你使用路由中间件,把你的逻辑放到
/middleware/routeGuard.global.ts
中,它会在每次路由解析事件时自动执行,文件将包含:编辑:但是,这仍然需要
/pages
目录中的内容或通过Vue路由器创建的一些路由。否则navigateTo
将失败,因为没有路由可供使用。下面是一个可能的方法示例:
https://stackblitz.com/edit/github-8wz4sj
基于从API返回的
pageType
,Nuxt路由守卫可以动态地将原始URL重新路由到特定的slug页面。