【问题标题】:How does the method menuDataRender() get its input for menuList?menuDataRender() 方法如何获取 menuList 的输入?
【发布时间】:2019-12-10 14:38:14
【问题描述】:

查看Ant Design Pro work 工作的以下片段,menuDataRender 方法如何获取其参数?我问这个的原因是因为我想修改签名,并且给定当前的调用方法,似乎没有传递任何参数。

方法:

const menuDataRender = (menuList: MenuDataItem[]): MenuDataItem[] =>
  menuList.map(item => {
    const localItem = {
      ...item,
      children: item.children ? menuDataRender(item.children) : [],
    };
    return Authorized.check(item.authority, localItem, null) as MenuDataItem;
  });

调用者:

  //
  //    ... code removed for brevity ...
  //
  return (
    <>
      <ProLayout
        logo={logo}
        menuHeaderRender={(logoDom, titleDom) => (
          <Link to="/">
            {logoDom}
            {titleDom}
          </Link>
        )}
        onCollapse={handleMenuCollapse}
        menuItemRender={(menuItemProps, defaultDom) => {
          if (menuItemProps.isUrl || menuItemProps.children) {
            return defaultDom;
          }

          return <Link to={menuItemProps.path}>{defaultDom}</Link>;
        }}
        breadcrumbRender={(routers = []) => [
          {
            path: '/',
            breadcrumbName: formatMessage({
              id: 'menu.home',
              defaultMessage: 'Home',
            }),
          },
          ...routers,
        ]}
        itemRender={(route, params, routes, paths) => {
          const first = routes.indexOf(route) === 0;
          return first ? (
            <Link to={paths.join('/')}>{route.breadcrumbName}</Link>
          ) : (
            <span>{route.breadcrumbName}</span>
          );
        }}
        footerRender={footerRender}
        menuDataRender={menuDataRender}                                        // <--- called here!
        formatMessage={formatMessage}
        rightContentRender={rightProps => <RightContent {...rightProps} />}
        {...props}
        {...settings}
      >
        <Authorized authority={authorized!.authority} noMatch={noMatch}>
          {children}
        </Authorized>
      </ProLayout>
      <SettingDrawer
        settings={settings}
        onSettingChange={config =>
          dispatch({
            type: 'settings/changeSetting',
            payload: config,
          })
        }
      />
    </>
  );
};

【问题讨论】:

    标签: reactjs typescript antd


    【解决方案1】:

    ProLayout 是来自@ant-design/pro-layout 包的BasicLayout 组件,该组件可以接收route 属性,默认为(GitHub):

    route = {
      routes: [],
    }
    

    routes键的值(默认为空数组)用于调用menuDataRender函数(GitHub):

    const { routes = [] } = route;
    
    if (menuDataRender) {
      renderMenuInfoData = getMenuData(
        routes,
        menu,
        formatMessage,
        menuDataRender,
      );
    }
    

    routes 数组中元素的预期架构是 Route 类型 (GitHub) 的数组:

    export interface MenuDataItem {
      authority?: string[] | string;
      children?: MenuDataItem[];
      hideChildrenInMenu?: boolean;
      hideInMenu?: boolean;
      icon?: string;
      locale?: string;
      name?: string;
      key?: string;
      path?: string;
      [key: string]: any;
      parentKeys?: string[];
    }
    
    export interface Route extends MenuDataItem {
      routes?: Route[];
    }
    

    示例:

    // routes.ts
    import { MenuDataItem } from "@ant-design/pro-layout/lib/typings";
    
    const routes : MenuDataItem[] = [
      {
        path: "/",
        name: "Home",
        authority: []
      },
      {
        path: "/users",
        name: "Users",
        authority: ["admin"]
      }
    ];
    
    export default routes;
    
    
    // app.ts
    import React from "react";
    
    import ProLayout, {
      MenuDataItem,
      BasicLayoutProps as ProLayoutProps,
    } from "@ant-design/pro-layout";
    
    import routeList from "./routes";
    
    const Application: React.FC<ProLayoutProps> = (props) => {
      const { children } = props;
    
      // or get your route list from where you have it (ex. from a store ...)
      // const routeList = useStoreState(state => state.app.routeList);
    
      const route = { routes: routeList };
    
      const menuDataRender = (menuList: MenuDataItem[]): MenuDataItem[] =>
        menuList.map(item => {
          const localItem = {
            ...item,
            children: item.children ? menuDataRender(item.children) : [],
          };
          return Authorized.check(item.authority, localItem, null) as MenuDataItem;
        });
    
      return (
        <ProLayout
          // more props
          route={route}
          menuDataRender={menuDataRender}
        >
         { children }
        </ProLayout>
      );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多