NextJs 基于API嵌套动态路由

NextJs nested dynamic routes based on API

我被 Nextjs 困住了:我需要根据我的(本地)数据创建嵌套动态路由。

以下是我想要创建的路线:

  1. .../cars/ -> 显示所有类别(轿车、suv、4x4)

  2. .../cars/category/ -> 显示类别中的汽车

    ex : .../cars/sedan -> 在轿车类别中显示汽车

  3. .../cars/category/id -> 显示类别为 id = 1

    的汽车的详细信息

    ex : .../cars/sedan/1 -> 显示 id = 1 的轿车的详细信息

路线 1 和路线 2 还可以,但我不知道最后一条该怎么做。你能帮帮我吗?

data.js

export const cars = [
  {
    id: 1,
    name: 'sedan',
    models: [
      {
        id: 1,
        name: 'model1',
        image: '/sedan1.jpg',
      },
      {
        id: 2,
        name: 'model2',
        image: '/sedan2.jpg',
      },
      {
        id: 3,
        name: 'model3',
        image: '/sedan3.jpg',
      },
    ],
  },
  {
    id: 2,
    name: 'suv',
    models: [
      {
        id: 1,
        name: 'model1',
        image: '/suv1.jpg',
      },
      {
        id: 2,
        name: 'model2',
        image: '/suv2.jpg',
      },
      {
        id: 3,
        name: 'model3',
        image: '/suv3.jpg',
      },
    ],
  },
  {
    id: 3,
    name: '4x4',
    models: [
      {
        id: 1,
        name: 'model1',
        image: '/4x4_1.jpg',
      },
      {
        id: 2,
        name: 'model2',
        image: '/4x4_2.jpg',
      },
      {
        id: 3,
        name: 'model3',
        image: '/4x4_3.jpg',
      },
    ],
  },
];

/cars/index.js

import { cars } from '../../data';
import Link from 'next/link';

export default function Categories({ car }) {
  return (
    {car.map((c) => (
      <Link key={c.id} href={`/cars/${c.name}`} passHref>
        <div>{c.name}</div>
      </Link>
    ))}
  );
}

export const getStaticProps = async () => {
  return {
    props: {
      car: cars,
    },
  };
}; 

/cars/[名称].js

import React from 'react';

import { cars } from '../../data';

export default function CategoriesCars({ cars }) {
  return (
    <div>
      {cars.models.map((m) => (
        <p key={m.id}>{m.name}</p>
      ))}
    </div>
  );
}

export const getStaticPaths = async () => {
  const paths = await cars.map((c) => ({
    params: {
      name: c.name,
    },
  }));
  return { paths, fallback: false };
};

export const getStaticProps = async (context) => {
  const { params } = context;
  const response = await cars.filter((c) => c.name === params.name);
  return {
    props: {
      cars: response[0],
    },
  };
};

页面文件夹必须是:

pages/
 cars/
  [category]/
   [id]/
    index.jsx
   index.jsx

然后转到 /cars/sedan/2 您可以像这样访问 categoryid 变量:

汽车/[类别]/[id]/index.jsx

import React from 'react';
import { useRouter } from 'next/router';

export default function Index() {
  const router = useRouter();
  // router.query.category -> sedan
  // router.query.id -> 2
  return <div>{JSON.stringify(router.query)}</div>;
}

// or 
export const getServerSideProps = async (context) => {
  const { params } = context;
  console.log(params); // { category: 'sedan', id: '2' }
  return {
    props: {
      cars: {},
    },
  };
};

// or if you wish use getStaticProps for SSG (with getStaticPaths)
export const getStaticPaths = async (context) => {
  const paths = cars
    .map((car) =>
      car.models.map((model) => ({
        params: {
          id: model.id.toString(),
          category: car.name,
        },
      }))
    )
    .flat(); // this is important

  return { paths, fallback: false };
};

export const getStaticProps = async (context) => {
  const { params } = context;
  console.log(params);
  return {
    props: {
      cars: {},
    },
  };
};

示例:StackBlitz