带重定向的 vue 路由映射

vue route mapping with redirects

我希望这是一个快速的。 我有这样的映射:

const routes = routeOptions.map((route) => {
  return {
    children: route?.children?.map((child) => {
      return {
        ...{
          path: child.path,
          name: child.name,
          meta: child.meta,
          alias: child.alias,
        },
        component: () =>
          import(
            /* webpackPrefetch: true */
            /* webpackChunkName: "[request]" */
            `../views/${child.name
                  .replace(" ", "-")
                  .toLowerCase()}/${child.name
                  .replace(" ", "-")
                  .toLowerCase()}.component.vue`
          ),
      };
    }),
    ...{
      path: route.path,
      name: route.name,
      meta: route.meta,
      redirect: route.redirect,
    },
    component: () =>
      import(
        /* webpackChunkName: "[request]" */
        `../views/${route.name
              .replace(" ", "-")
              .toLowerCase()}/${route.name
              .replace(" ", "-")
              .toLowerCase()}.component.vue`
      ),
  };
});

然后我可以这样设置 routeOptions

const routeOptions: RouteOptions[] = [{
    path: "/account",
    name: "account",
    meta: {
      title: "Account",
    },
    redirect: {
      name: "sign-in",
    },
    children: [{
        path: "sign-in",
        name: "sign-in",
        meta: {
          title: "Sign in",
        },
      },
      {
        path: "join",
        name: "join",
        meta: {
          title: "Join",
        },
      },
      {
        path: "add-password",
        name: "add-password",
        meta: {
          title: "Add password",
        },
      },
      {
        path: "forgot-password",
        name: "forgot-password",
        meta: {
          title: "Forgot password",
        },
      },
      {
        path: "reset-password",
        name: "reset-password",
        meta: {
          title: "Reset password",
        },
      },
    ],
  },
  {
    path: "/crew",
    name: "staff",
    meta: {
      title: "Crew",
    },
    redirect: {
      name: "staff-account",
    },
    children: [{
        path: "account",
        name: "staff-account",
        meta: {
          title: "Account",
          authorize: ["Venue Staff", "Venue Manager"],
        },
      },
      {
        path: "demos",
        name: "staff-demos",
        meta: {
          title: "Demos",
          authorize: ["Venue Staff", "Venue Manager"],
        },
      },
      {
        path: "leader-boards",
        name: "staff-leader-boards",
        meta: {
          title: "Leader boards",
          authorize: ["Venue Staff", "Venue Manager"],
        },
      },
      {
        path: "search",
        name: "staff-search",
        meta: {
          title: "Search",
          authorize: ["Venue Staff", "Venue Manager"],
        },
      },
      {
        path: "stories",
        name: "staff-stories",
        meta: {
          title: "Stories",
          authorize: ["Venue Staff", "Venue Manager"],
        },
      },
    ],
  },
  {
    path: "/404",
    name: "not-found",
    meta: {
      title: "Page not found",
    },
  },
  {
    path: "*",
    name: "layout",
    meta: {},
    children: [{
        path: "/business/live-better",
        name: "blog",
        meta: {
          title: "Partner Blog",
        },
        children: [{
          path: ":title",
          name: "blog",
        }, ],
      },
      {
        path: "/business/live-better/:title",
        name: "blog-post",
      },
      {
        path: "/brands",
        name: "brand-list",
        meta: {
          title: "Brands",
        },
      },
      {
        path: "/brands/:brandSlug",
        name: "brand-details",
        meta: {
          title: "Details",
        },
      },
      {
        path: "/categories",
        redirect: {
          name: "categories"
        },
      },
      {
        path: "/categories/:categorySlug",
        redirect: {
          name: "product-list"
        },
      },
      {
        path: "/categories/:categorySlug/:productId/:productTitle",
        redirect: {
          name: "product-details"
        },
      },
      {
        path: "/products",
        name: "categories",
        meta: {
          title: "Products",
        },
      },
      {
        path: "/products/:categorySlug",
        name: "product-list",
        meta: {
          title: "Products",
        },
      },
      {
        path: "/products/:categorySlug/:productId/:productTitle",
        name: "product-details",
        meta: {
          title: "Details",
        },
      },
      {
        path: "/favourites",
        name: "favourites",
        meta: {
          title: "Your favourites",
        },
      },
      {
        path: "/feedback",
        name: "consumer-feedback",
        meta: {
          title: "Your feedback",
          authorize: [],
        },
      },
      {
        path: "/venues/:venueSlug/theatres",
        name: "theatre-list",
        meta: {
          title: "Theatres",
        },
      },
      {
        path: "/venues/:venueSlug/theatres/:theatreSlug",
        name: "theatre-details",
        meta: {
          title: "Theatre",
        },
      },
      {
        path: "/venues",
        name: "venue-list",
        meta: {
          title: "Venues",
        },
      },
      {
        path: "/venues/:venueSlug",
        name: "venue-details",
        meta: {
          title: "Details",
        },
      },
      {
        path: "/search",
        name: "search",
        meta: {
          title: "Search results",
        },
      },
      {
        path: "*",
        name: "home",
        meta: {
          title: "Home",
        },
      },
    ],
  },
];

其中大部分工作正常,但如果您在此处查看此部分:

{
  path: "/categories",
  redirect: { name: "categories" },
},
{
  path: "/categories/:categorySlug",
  redirect: { name: "product-list" },
},
{
  path: "/categories/:categorySlug/:productId/:productTitle",
  redirect: { name: "product-details" },
},

我希望这些重定向到其他命名视图。 我的映射目前的工作方式是它获取名称并在 views 文件夹中查找匹配的模板,但这些路由没有模板,因为它们只是重定向。 有谁知道我可以对我的代码做些什么来使其与这些一起工作?

我是这样做的:

const createChildRoutes = (children) => {
  return children?.map((child) => {
    const childRoute = {
      path: child.path,
      name: child.name,
      meta: child.meta,
      alias: child.alias,
      redirect: child.redirect,
    };

    if (child.name) {
      return {
        ...childRoute,
        component: () =>
          import(
            /* webpackPrefetch: true */
            /* webpackChunkName: "[request]" */ `../views/${child.name
              .replace(" ", "-")
              .toLowerCase()}/${child.name
              .replace(" ", "-")
              .toLowerCase()}.component.vue`
          ),
      };
    } else {
      return childRoute;
    }
  });
};

const routes = routeOptions.map((route) => {
  const mainRoute = {
    path: route.path,
    name: route.name,
    meta: route.meta,
    alias: route.alias,
    redirect: route.redirect,
  };

  if (route.name) {
    return {
      children: createChildRoutes(route?.children),
      ...mainRoute,
      component: () =>
        import(
          /* webpackPrefetch: true */
          /* webpackChunkName: "[request]" */ `../views/${route.name
            .replace(" ", "-")
            .toLowerCase()}/${route.name
            .replace(" ", "-")
            .toLowerCase()}.component.vue`
        ),
    };
  } else {
    return {
      children: createChildRoutes(route?.children),
      ...mainRoute,
    };
  }
});