我是 nuxt 的新手,面临着一个任务,我应该使用多个可选的路由参数。我想让我的应用程序尽可能简单,所以我会避免使用任何额外的包。 据我所知,nuxt3 路由取决于文件夹结构,所以这就是问题所在:
假设我们有一个
/foo
路线,其中可以有2个可选参数, paramA
和 paramB
这可以通过以下文件夹结构来完成:
pages/
-foo/
--index.vue
--[paramA]/
---index.vue
---[[paramB]].vue
有效,但是这样页面会为每个参数重复。
最佳做法是什么?谢谢
我最终得到了自定义路线:
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)
})
}
}
其他答案似乎比必要的要复杂得多。通过在文件和文件夹名称中使用双方括号,您可以创建一个可选的路由参数。 (单方括号将创建一个非可选的路由参数)。
所以要创建 URL
.../foo/:paramA?/:paramB?
您可以使用以下文件结构。
pages/ (folder)
-foo/ (folder)
--[[paramA]]/ (folder)
---[[paramB]].vue (file with actual page)
当导航到 URL
.../foo
页面 [[paramB]].vue
将被使用。
对于像这样
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
对于使用多级路径、组件和子组件、子子组件等的复杂路由系统,并且仅当路径参数存在时才加载每个父/子组件,您可以使用这样的函数:
~/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);
},
...
]
这样就可以只在特定参数被通知时才分层加载组件。每个父组件在子组件之前呈现。生成包含所有聚合组件的视图。我相信通过这种方式,仅使用路由系统就可以很容易地创建更多动态页面。