动态 Nuxt 页面选择
Posted
技术标签:
【中文标题】动态 Nuxt 页面选择【英文标题】:Dynamic Nuxt page selection 【发布时间】:2020-07-04 19:00:43 【问题描述】:基本上,我正在尝试为匹配的路由动态选择一个组件,或者进行内部重写,这样我就可以在不更改 url 的情况下选择不同的路由。
我现在的解决方案:
我有来自我想要匹配的外部资源的 url,我正在使用 _.js
在 Nuxt 中使用通配符页面捕获这些。在此页面上的中间件中,我将确定它应该是页面的实际类型(cmspage、productdetail 等)并将结果放入存储中。然后我会检查是否在 validate 函数中找到数据,以便在需要时返回 404。如果成功,将使用渲染函数渲染components/pages/cms.vue
或任何类型的页面。
所以这应该可以工作(仍然需要大部分实现)但是它有一个问题是我不能使用很多可用的 Nuxt 功能(中间件、asyncData、获取、验证等等?)这正是我想要实现的页面。
这个 nuxt 配置扩展不起作用,但会很完美:
router:
extendRoutes(routes, resolve)
routes.push(
path: '*',
component: async () =>
const pageType = 'pdp' // await getPageType()
switch (pageType)
case 'cms':
return resolve(__dirname, 'pages/cmsPage.vue')
case 'pdp':
return resolve(__dirname, 'pages/productDetailPage.vue')
case 'plp':
return resolve(__dirname, 'pages/productListPage.vue')
)
【问题讨论】:
如何确定应该显示哪个页面?什么决定了pageType
?。 URL 是否确定要显示的页面类型?
@ajobi,是的,该 url 被发送到 magento 和 drupal 以检查他们是否可以解决它,从而确定它是 cms、product 还是 productlistpage。
好的,他们是如何确定的?他们可能会解析 url 寻找蛞蝓等吗?
我相信他们有一个 db 表,他们可以在其中查找完整的 slug,因此我无法匹配特定 url 结构上的页面类型。
你确定吗?因为那将是解决它的明显且正确的方法。我看不出为什么一个产品应该在 product/product-name
之下,而另一个产品应该在一个完全不同的 slug 之下
【参考方案1】:
我不确定我的问题是否正确,但我认为:
您需要一条路径(路线)来显示不同的(动态)视图 在路由加载之前,您想要获取页面类型(可能来自后端) 如果这些组件与路由不匹配,您不希望将这些组件加载到您的应用程序中所以,如果这是您想要的,请按照以下说明操作:
内部路线你需要这样的东西:
let pageType = null;
export default new VueRouter(
mode: "history",
routes: [
//... other routes
path: "/dynamic-page",
component: () => import("./components/DynamicPage"),
props: router => ( pageType ),
beforeEnter(to, from, next)
// getPageType() is supposed as a async method getting the page type
getPageType().then(type =>
pageType = type;
next();
);
]
);
因此,使用上面的代码,我们获取了pageType
并将其作为prop
传递给组件。
<template>
<div class="dynamic-page">
<component :is="pageType"/>
</div>
</template>
<script>
export default
props:
pageType: String
,
components:
ProductList: () => import("../dynamic-pages/ProductListPage"),
Cms: () => import("../dynamic-pages/CmsPage"),
ProductDetail: () => import("../dynamic-pages/ProductDetailPage")
;
</script>
因此,使用延迟加载的组件将仅加载 1 个组件。这是由pageType
prop 定义的。
我发了CodeSandbox example
【讨论】:
这看起来很像我现在没有 Nuxt 的解决方案,问题是 Nuxt 具有在页面上执行的特殊功能,而不是在组件(中间件、asyncData 等)上执行。这实际上是我想保留的功能,最好让动态页面的行为与 pages 目录中的任何普通页面完全相同。【参考方案2】:我不确定我的问题是否正确,但我认为:
您希望根据某些条件动态加载页面。
我有这个解决方案。
import Vue from "vue";
import VueRouter from "vue-router";
import HomePage from "./components/HomePage";
Vue.use(VueRouter);
function getRandomPage()
const pageTypes = ["ProductList", "Cms", "ProductDetail"];
let min = 0;
let max = 2;
min = Math.ceil(min);
max = Math.floor(max);
const random = Math.floor(Math.random() * (max - min + 1)) + min;
return pageTypes[random];
let pageType = null;
function getPageType()
return new Promise(res => setTimeout(res(getRandomPage()), 1500));
export default new VueRouter(
mode: "history",
routes: [
path: "/",
component: HomePage
,
path: "/dynamic-page",
component: () =>
let page = "ProductListPage.vue"
getPageType().then(type =>
pageType = type;
console.log(pageType)
if (pageType === "ProductList")
page = "ProductListPage.vue";
else if (pageType === "Cms")
page = "CmsPage.vue";
else
page = "ProductDetailPage.vue";
)
return import("./dynamic-pages/" + page)
,
]
);
【讨论】:
【参考方案3】:我遇到了同样的问题,我在 github 上找到了这个 PR:https://github.com/nuxt/nuxt.js/pull/7754
解决方案是这样的:
router:
async extendRoutes(routes, resolve)
const pageType = await getPageType()
let component
switch (pageType)
case 'cms':
component = resolve(__dirname, 'pages/cmsPage.vue')
case 'pdp':
component = resolve(__dirname, 'pages/productDetailPage.vue')
case 'plp':
component = resolve(__dirname, 'pages/productListPage.vue')
routes.push(
path: '*',
component
)
已在 v2.14.0 中合并,在我的项目中运行良好!
【讨论】:
实际上它并没有那么好用,因为路由是在构建时间而不是动态构建的(当用户要求路由时)......我一直在寻找最好的方法。跨度>以上是关于动态 Nuxt 页面选择的主要内容,如果未能解决你的问题,请参考以下文章