react 组合组件(模拟 antd <Input.TextArae /> 用法)

        模拟 antd <Input.TextArae /> 用法,写了一个 ListLayout 布局的组件,目的为了减少一些重复的代码。

        ListLayout.Content 放置页面显示的主要内容。
        ListLayout.NavBar 页面置顶的跳转内容。
        ListLayout.QueryBar 查询条件输入框及重置,查询和导出按钮。
        ListLayout.ToolsBar 放置 Button 一类的按钮。在放 ListLayout.Content。

import { Breadcrumb, Space } from 'antd';
import { ItemType } from 'antd/es/breadcrumb/Breadcrumb';

import { Main } from 'common/components/Main'

import Head from 'next/head';

import { Children, forwardRef } from 'react'

import type { CSSProperties, LegacyRef, ReactNode } from 'react'

type NodeProps = {
  children: ReactNode;
}

type LayoutProps = NodeProps & {
  title: string;
}

const layoutStyle: CSSProperties = {
  marginTop: 10,
  marginLeft: 15, 
  marginRight: 15,
  backgroundColor: 'white',
}

const Content = (props: NodeProps) => {
  return (
    <div style={{...layoutStyle}}>
      {props.children}
    </div>
  );
}

const NavBar = (props: NodeProps & {items?: ItemType[]}) => {
  return (
    <div style={{backgroundColor: 'white',paddingTop: 10, paddingRight: 20, paddingBottom: 10, paddingLeft: 20}}>
      <Breadcrumb items={props.items ? props.items: Children.map(props.children, (it) => ({title: it})) as ItemType[]} />
    </div>
  );
}

const QueryBar = (props: NodeProps) => {
  return (
    <div style={{...layoutStyle, overflowX: 'hidden', paddingTop: 24}}>
      {props.children}
    </div>
  );
}

const ToolsBar = (props: NodeProps & {style?: CSSProperties}) => {
  return (
    <Space style={{ display: 'flex', justifyContent: 'flex-end', padding: '10px 20px', ...props.style }}>
      {props.children}
    </Space>
  );
}

const Layout = forwardRef((props: LayoutProps, ref: LegacyRef<HTMLDivElement>) => {
  return (
    <div ref={ref} style={{ backgroundColor: '#F0F2F5', width: '100%', height: '100%' }}>
      <Head>
        <title>{props.title}</title>
      </Head>
      <Main>
        {props.children}
      </Main>
    </div>
  );
});

type LayoutType = typeof Layout;

type CompoundedComponent = LayoutType & {
  Content: typeof Content;
  NavBar: typeof NavBar;
  QueryBar: typeof QueryBar;
  ToolsBar: typeof ToolsBar;
};

const ListLayout: CompoundedComponent = Layout as CompoundedComponent;

ListLayout.Content = Content;
ListLayout.NavBar = NavBar;
ListLayout.QueryBar = QueryBar;
ListLayout.ToolsBar = ToolsBar;

export { ListLayout };
<ListLayout title="测试">
  <ListLayout.NavBar>
    <a href="#">测试1</a>
    <a href="#">测试2</a>
  </ListLayout.NavBar>
  <ListLayout.QueryBar>
    <Form form={form} initialValues={{test2: [{value: '123', label: '123'}]}} style={{padding: '0 20px'}}>
      <Form.Item name="test2" rules={[{required: true}]} label="测试标题">
        <Select mode="multiple" allowClear style={{width: 237}}
          fieldNames={{label: 'name', value: 'id'}}
        >
          {/* <Form.Item name="query1" label="查询1">
            <Input />
          </Form.Item>
          <Form.Item name="query2" label="查询2">
            <Input />
          </Form.Item> */}
        </Select>
      </Form.Item>
    </Form>
  </ListLayout.QueryBar>
  <ListLayout.Content>
    <ListLayout.ToolsBar>
      <Button
        onClick={() => {
          form.validateFields().then(() => {
            alert(JSON.stringify(form.getFieldsValue()));
          });
        }}
      >测试1</Button>
      <Button>测试2</Button>
    </ListLayout.ToolsBar>
    <Table size="small" columns={columns} />
  </ListLayout.Content>
</ListLayout>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值