簡體   English   中英

如何為帶有多級下拉菜單的邊欄中的嵌套項創建動態路由器?

[英]How to create dynamic router for nested items in a sidebar with multilevel dropdown?

這是我目前的代碼,但路徑不是動態的,每當下拉列表中有一個新部分時,我都必須對路徑進行硬編碼,無論如何我可以寫一個 function 來自動生成這些路徑嗎? (第一個是生成多級側邊欄,第二個文件是路由器,第三個文件是點擊側邊欄中的某個部分時頁面中的內容)

import React from "react";
import * as AiIcons from "react-icons/ai";
import * as IoIcons from "react-icons/io";

export const SidebarData = [
  {
    label: "Vertical App",
    path: "/verticalapp",
    icon: <AiIcons.AiFillHome />,
    id: 1,
    branches: [
      {
        label: "Weather App",
        path: "/verticalapp/weatherapp",
        icon: <IoIcons.IoIosPaper />,
        id: 2,
        branches: [],
      },
      {
        label: "Occupancy App",
        path: "/verticalapp/occupancyapp",
        icon: <IoIcons.IoIosPaper />,
        id: 3,
        branches: [],
      },
    ],
  },
  {
    label: "Company",
    path: "/company",
    icon: <IoIcons.IoIosPaper />,
    id: 4,
    branches: [
      {
        label: "Reseller",
        path: "/company/reseller",
        icon: <IoIcons.IoIosPaper />,
        id: 5,
        branches: [
          {
            label: "Client 1",
            path: "/company/reseller/client1",
            icon: <IoIcons.IoIosPaper />,
            id: 6,
            branches: [
              {
                label: "Client 11",
                path: "/company/reseller/client11",
                icon: <IoIcons.IoIosPaper />,
                id: 7,
                branches: [],
              },
            ],
          },
          {
            label: "Client 2",
            path: "/company/reseller/client2",
            icon: <IoIcons.IoIosPaper />,
            id: 8,
            branches: [
              {
                label: "Client 21",
                path: "/company/reseller/client21",
                icon: <IoIcons.IoIosPaper />,
                id: 9,
                branches: [],
              },
              {
                label: "Client 22",
                path: "/company/reseller/client22",
                icon: <IoIcons.IoIosPaper />,
                id: 10,
                branches: [],
              },
            ],
          },
        ],
      },
      {
        label: "Client",
        path: "/company/client",
        icon: <IoIcons.IoIosPaper />,
        id: 11,
        branches: [
          {
            label: "Client 3",
            path: "/company/client/client3",
            icon: <IoIcons.IoIosPaper />,
            id: 12,
            branches: [],
          },
          {
            label: "Client 4",
            path: "/company/client/client4",
            icon: <IoIcons.IoIosPaper />,
            id: 13,
            branches: [],
          },
        ],
      },
      {
        label: "Consumer",
        path: "/company/consumer",
        icon: <IoIcons.IoIosPaper />,
        id: 14,
        branches: [],
      },
    ],
  },
  
  {
    label: "Contact Us",
    path: "/contactus",
    icon: <IoIcons.IoMdHelpCircle />,
    id: 20,
    branches: [],
  },
];
import './App.css';
import Sidebar from './components/Sidebar';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import VerticalApp from './pages/VerticalApp';
//import { Company, Reseller, Client, Consumer, Client1, Client2 } from './pages/Company';
import {Company} from './pages/Company';

function App() {
  return (
    <Router>
      <Sidebar />
      <Switch>
        <Route path='/verticalapp' exact component={VerticalApp} />
        <Route path='/company' exact component={Company} />
        {/* <Route path='/company/:label' component={Company} /> */}
        {/* <Route path='/company/reseller' exact component={Reseller} />
        <Route path='/company/client' exact component={Client} />
        <Route path='/company/consumer' exact component={Consumer} />
        <Route path='/company/reseller/client1' exact component={Client1} />
        <Route path='/company/reseller/client2' exact component={Client2} /> */}
      </Switch>
    </Router>
  );
}

export default App;
import React from "react";

export const Company = () => {
  return (
    <div className="reports">
      <h1>Company</h1>
    </div>
  );
};

export const Reseller = () => {
  return (
    <div className="reports">
      <h1>Company/Reseller</h1>
    </div>
  );
};

export const Client = () => {
  return (
    <div className="reports">
      <h1>Company/Client</h1>
    </div>
  );
};

export const Consumer = () => {
  return (
    <div className="reports">
      <h1>Company/Consumer</h1>
    </div>
  );
};

export const Client1 = () => {
  return (
    <div className="reports">
      <h1>Company/Reseller/Client1</h1>
    </div>
  );
};

export const Client2 = () => {
  return (
    <div className="reports">
      <h1>Company/Reseller/Client2</h1>
    </div>
  );
};

您可以將路由道具添加到sidebarData並遞歸構建一個路由數組。

例子:

const sidebarData = [
  {
    label: "Vertical App",
    path: "/verticalapp",
    icon: <AiIcons.AiFillHome />,
    id: 1,
    routeProps: {
      render: () => <h1>Vertical App</h1>
    },
    branches: [
      {
        label: "Weather App",
        path: "/verticalapp/weatherapp",
        icon: <IoIcons.IoIosPaper />,
        id: 2,
        branches: []
      },
      {
        label: "Occupancy App",
        path: "/verticalapp/occupancyapp",
        icon: <IoIcons.IoIosPaper />,
        id: 3,
        branches: []
      }
    ]
  },
  {
    label: "Company",
    path: "/company",
    icon: <IoIcons.IoIosPaper />,
    id: 4,
    routeProps: {
      component: Company
    },
    branches: [
      {
        label: "Reseller",
        path: "/company/reseller",
        icon: <IoIcons.IoIosPaper />,
        id: 5,
        routeProps: {
          component: Reseller
        },
        branches: [
          {
            label: "Client 1",
            path: "/company/reseller/client1",
            icon: <IoIcons.IoIosPaper />,
            id: 6,
            routeProps: {
              component: Client1
            },
            branches: [
              {
                label: "Client 11",
                path: "/company/reseller/client11",
                icon: <IoIcons.IoIosPaper />,
                id: 7,
                branches: []
              }
            ]
          },
          {
            label: "Client 2",
            path: "/company/reseller/client2",
            icon: <IoIcons.IoIosPaper />,
            id: 8,
            routeProps: {
              component: Client2
            },
            branches: [
              {
                label: "Client 21",
                path: "/company/reseller/client21",
                icon: <IoIcons.IoIosPaper />,
                id: 9,
                branches: []
              },
              {
                label: "Client 22",
                path: "/company/reseller/client22",
                icon: <IoIcons.IoIosPaper />,
                id: 10,
                branches: []
              }
            ]
          }
        ]
      },
      {
        label: "Client",
        path: "/company/client",
        icon: <IoIcons.IoIosPaper />,
        id: 11,
        routeProps: {
          component: Client
        },
        branches: [
          {
            label: "Client 3",
            path: "/company/client/client3",
            icon: <IoIcons.IoIosPaper />,
            id: 12,
            branches: []
          },
          {
            label: "Client 4",
            path: "/company/client/client4",
            icon: <IoIcons.IoIosPaper />,
            id: 13,
            branches: []
          }
        ]
      },
      {
        label: "Consumer",
        path: "/company/consumer",
        icon: <IoIcons.IoIosPaper />,
        id: 14,
        routeProps: {
          component: Consumer
        },
        branches: []
      }
    ]
  },

  {
    label: "Contact Us",
    path: "/contactus",
    icon: <IoIcons.IoMdHelpCircle />,
    id: 20,
    routeProps: {
      render: () => <h1>About Us</h1>
    },
    branches: []
  }
];

計算路線

const routes = (data) =>
  data
    // include only data items with route props
    .filter(({ routeProps }) => !!routeProps)
    // recursively get "nested" routes, flatten to single array
    .flatMap(({ branches, id, path, routeProps }) => [
      ...routes(branches),
      { id, path, ...routeProps }
    ]);

const getRoutes = (data) =>
  routes(data)
    // sort more specific routes before less specific routes
    .sort((a, b) => b.path.localeCompare(a.path))
    // map to Route component
    .map(({ id, path, ...routeProps }) => (
      <Route key={id} path={path} {...routeProps} />
    ));

...

<Switch>
  {getRoutes(sidebarData)}
</Switch>

編輯 how-to-create-dynamic-router-for-nested-items-in-a-sidebar-with-multilevel-dropd

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM