Nuxt3 多个可选路由参数

问题描述 投票:0回答:4

我是 nuxt 的新手,面临着一个任务,我应该使用多个可选的路由参数。我想让我的应用程序尽可能简单,所以我会避免使用任何额外的包。 据我所知,nuxt3 路由取决于文件夹结构,所以这就是问题所在:

假设我们有一个

/foo
路线,其中可以有2个可选参数,
 paramA
 paramB

这可以通过以下文件夹结构来完成:

pages/
 -foo/
 --index.vue
 --[paramA]/
 ---index.vue
 ---[[paramB]].vue

有效,但是这样页面会为每个参数重复。

最佳做法是什么?谢谢

nuxt.js nuxtjs3
4个回答
1
投票

我最终得到了自定义路线:

routes.js

import { resolve } from 'path'
export const customRoutes = [
  {
    name: 'foo',
    path: '/foo/:interest?/:id?',
    file: resolve(__dirname, 'pages/test.vue')
  }
];

nuxt.config.ts

import { customRoutes } from "./routes.js";
export default defineNuxtConfig({
    hooks: {
    "pages:extend": (pages) => {
      customRoutes.forEach((customRoute) => {
        pages.push(customRoute)
      })
    }
  }

1
投票

其他答案似乎比必要的要复杂得多。通过在文件和文件夹名称中使用双方括号,您可以创建一个可选的路由参数。 (单方括号将创建一个非可选的路由参数)。

所以要创建 URL

.../foo/:paramA?/:paramB?
您可以使用以下文件结构。

pages/               (folder)
-foo/                (folder)
--[[paramA]]/        (folder)
---[[paramB]].vue    (file with actual page)

当导航到 URL

.../foo
页面
[[paramB]].vue
将被使用。


0
投票

对于像这样

mywebsite.com/param1/param2/param3
这样有多个参数的URL,你需要这样的结构:

pages
└── [param1]
    └── [param2]
        └── [param3].vue

要在控制台中显示它,请将其放入

[param3].vue

<script setup>
import { useRoute } from "vue-router";
const route = useRoute();
console.log(route.params);
</script>

参考。 https://nuxt.com/docs/guide/directory-structure/pages#nested-routes


0
投票

对于使用多级路径、组件和子组件、子子组件等的复杂路由系统,并且仅当路径参数存在时才加载每个父/子组件,您可以使用这样的函数:

~/extends/pages/RoutesCrud.ts

import { resolve } from "path";

export class RoutesCrud {
  static handle(nuxt: any) {
    nuxt.hook("pages:extend", async (pages: Array<any>) => {
      pages.push({
        name: "crud2",
        path: "/crud2",
        file: resolve("/components/crud/AppCrud.vue"),
        children: await deep1(),
      });
    });
  }
}

async function deep1() {
  return [
    {
      name: "CrudPath",
      path: "/crud2/:path",
      file: resolve("/components/crud/deep1/CrudDeep1List.vue"),
      children: [
        {
          name: "CrudDeep1Id",
          path: "/crud2/:path/:deep1Id",
          file: resolve("/components/crud/deep1/CrudDeep1Form.vue"),
          children: await deep2(),
        },
      ],
    },
  ];
}

async function deep2() {
  return [
    {
      name: "CrudDeep2Path",
      path: "/crud2/:path/:deep1Id/:deep2Path",
      file: resolve("/components/crud/deep2/CrudDeep2List.vue"),
      children: [
        {
          name: "CrudDeep2Id",
          path: "/crud2/:path/:deep1Id/:deep2Path/:deep2Id",
          file: resolve("/components/crud/deep2/CrudDeep2Form.vue"),
          children: await deep3(),
        },
      ],
    },
  ];
}

async function deep3() {
  return [
    {
      name: "CrudDeep3Path",
      path: "/crud2/:path/:deep1Id/:deep2Path/:deep2Id/:deep3Path",
      file: resolve("/components/crud/deep3/CrudDeep3List.vue"),
      children: [
        {
          name: "CrudDeep3Id",
          path: "/crud2/:path/:deep1Id/:deep2Path/:deep2Id/:deep3Path/:deep3Id",
          file: resolve("/components/crud/deep3/CrudDeep3Form.vue"),
          children: await deep4(),
        },
      ],
    },
  ];
}

async function deep4() {
  return [
    {
      name: "CrudDeep4Path",
      path: "/crud2/:path/:deep1Id/:deep2Path/:deep2Id/:deep3Path/:deep3Id/:deep4Path",
      file: resolve("/components/crud/deep4/CrudDeep4List.vue"),
      children: [
        {
          name: "CrudDeep4Id",
          path: "/crud2/:path/:deep1Id/:deep2Path/:deep2Id/:deep3Path/:deep3Id/:deep4Path/:deep4Id",
          file: resolve("/components/crud/deep4/CrudDeep4Form.vue"),
          children: await deep5(),
        },
      ],
    },
  ];
}

// eslint-disable-next-line require-await
async function deep5() {
  return [
    {
      name: "CrudDeep5Path",
      path: "/crud2/:path/:deep1Id/:deep2Path/:deep2Id/:deep3Path/:deep3Id/:deep4Path/:deep4Id/:deep5Path",
      file: resolve("/components/crud/deep5/CrudDeep5List.vue"),
      children: [
        {
          name: "CrudDeep5Id",
          path: "/crud2/:path/:deep1Id/:deep2Path/:deep2Id/:deep3Path/:deep3Id/:deep4Path/:deep4Id/:deep5Path/:deep5Id",
          file: resolve("/components/crud/deep5/CrudDeep5Form.vue"),
        },
      ],
    },
  ];
}


在 nuxt.config.ts 中,导入类。

import { RoutesCrud } from "./extends/pages/RoutesCrud";
...
modules: [
...
  // Inject pages:extend to nuxt hooks
  async (options, nuxt) => {
    await RoutesCrud.handle(nuxt);
  },

...
]

这样就可以只在特定参数被通知时才分层加载组件。每个父组件在子组件之前呈现。生成包含所有聚合组件的视图。我相信通过这种方式,仅使用路由系统就可以很容易地创建更多动态页面。

© www.soinside.com 2019 - 2024. All rights reserved.