动态Nuxt页面选择

基本上,我试图为匹配的路由动态选择一个组件或进行内部重写,以便我可以选择其他路由而不更改url。

现在我的解决方案:我有一个我想匹配的外部资源的url,我正在使用Nuxt中的通配符页面捕获这些URL _.js在此页面上的中间件中,我将确定页面的实际类型(cmspage,productdetail等),并将结果放入商店中。然后,我将检查是否在validate函数中找到了数据,以便在需要时可以返回404。如果成功,则将使用render函数来渲染components/pages/cms.vue或任何类型的页面。

So this should work (still need most of the implementation) but it has the problem that I can't use a lot of Nuxt features (middleware, asyncData, fetch, validate, more?) that are available for pages which is exactly what I'm trying to achieve.

This nuxt config extension doesn't work but would be perfect:

{
  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')
          }
        }
      })
    }
  }
}
达蒙2020/04/03 10:54:00

我不确定我是否正确回答了这个问题,但我认为:

您要根据某些条件动态加载页面。

我有这个解决方案。

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)
      },
    }
  ]
});
宝儿理查德2020/04/03 10:54:00

我不确定我是否正确回答了这个问题,但我认为:

  • 您需要一个单一的路径(路线)来显示不同的(动态)视图
  • 在路由加载之前,您要获取页面类型(可能是从后端获取)
  • 您不希望那些与路线不匹配的组件加载到您的应用程序中

因此,如果您要这样做,请按照以下步骤操作:


  • 在路线内部,您需要这样的东西:

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个组件。这是由pageTypeprop 定义的

我做了一个CodeSandbox示例