antd-react 组件库工作以来的总结

这篇博客总结了作者在使用antd-react组件库时的经验,涵盖了从准备阶段到组件的详细使用,包括通用组件如Button和Icon,布局组件如Grid和Layout,数据录入组件如Form和DatePicker,数据展示组件如Table和Avatar,以及反馈和其它组件等。内容丰富,包含各种组件的使用场景和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

antd-react 组件库工作以来的总结

  • 我的博客
  • http://wangxince.site/my-demo-markdown/

准备阶段

bug

# form
当与modal结合的时候 initValus数据会异步
需要使用form.setValues 设置数据
具体见 http://wangxince.site/my-demo-markdown/debug

组件

通用

button
 <Button
    # 基础属性
    // 样式
    type={
   'default |primary | dashed | text | link'}
    // 形状
    shape={
   'default|circle|round'}
    // 大小
    size={
   'large|middle|small'}
    // 特殊样式
    ghost    按钮背景透明
    danger   红色外观
    disabled 禁用效果
    block    宽度为父宽度
    // 设置图标
    icon={
   <xxx/>}
    
    # 其他属性
    // loading 效果控制
    loading={
   boolean}
  />
      
 # 组合按钮
// 点击就弹出一个组件 
<Dropdown.Button overlay={
   组件名} />
 # bug  移除按钮文件之间的空格
import {
    Button, ConfigProvider } from 'antd';
 <ConfigProvider autoInsertSpaceInButton = {
    false }> 
       <Button type="primary">
              空格
      </Button>
</ConfigProvider>
icon
# 默认图标
import {
    xxx } from '@ant-design/icons';
# 自定义图标
import Icon from '@ant-design/icons';
<Icon component={
   xxx} />
# 使用 iconfont
import {
    createFromIconfontCN } from '@ant-design/icons';
const IconFont = createFromIconfontCN({
   
  scriptUrl: '//at.alicdn.com/t/font_8d5l8fzk5b87iudi.js',
});
<IconFont type="icon-tuichu" />
# 三类图标名字区别
xxxOutlined
Fuiled
TwoTone
  
# spin                    旋转动画
# rotate={
   180}            旋转角度
# twoToneColor="#eb2f96"  双色图标设置颜色
排版

布局

分割线
<Divider >
   // 是否虚线
   dashed
   // 文字是否为普通正文样式
   plain                         
   // 分割线位置
   orientation={
   'left|right'}
   type={
   'horizontal|vertical'}
/>
Grid
# row
<Row
  // 间隔
  gutter={
   16}
  gutter={
   {
    xs: 8, sm: 16, md: 24, lg: 32 }}
  gutter={
   [16, 24]}   水平间距 垂直间距
  // flex布局
  justify='start|center|spacce-between....'
  // 子元素对齐方式
  align='top|middle|bottom'
  // 换行
  wrap={
   false}
  
/>
# col
<Col
  // 划分块数 共24份
  span={
   6}
  // 左右偏移 向右偏移6
  offset={
   6}
  // 向左
  pull={
   18}
  // 向右
  push={
   2}
/>
<Row>
    
# 手动指定栅格宽度
默认一格为 8.33333%

style="width: 12.499999995%;
    flex: 0 0 12.499%;max-width: 12.499%;">
Layout
import {
    Layout } from 'antd';
const {
    Header, Footer, Sider, Content } = Layout;

 <Layout>
      <Header>Header</Header>
      <Content>Content</Content>
      <Footer>Footer</Footer>
       <Layout>
        <Sider>Sider</Sider>
        <Content>Content</Content>
      </Layout>
  </Layout>
Space
// 设置组件之间的间距
<Space
  size='small|middle|large|number'
  // 自定义间距大小
  size={
   [8,16]}
  align='start|end|center|baseline'
  direction="vertical|horizontal"
  wrap
  // 相邻组件分隔符
  split={
   <Divider type="vertical" />}
/>

导航

Affix 固钉
<Affix 
  // 粘性定位
  offsetTop={
   10}
  offsetBottom={
   10}
  // 滚动元素对象
  target={
   ()=>dom}
  onChange
/>
Breadcrumb
  <Breadcrumb 
    // 总体自定义分隔符
    separator=">"
  >
    <Breadcrumb.Item>
      <a href="">Application Center</a>
    </Breadcrumb.Item>
    // 子项 自定义分隔符
    <Breadcrumb.Separator>:</Breadcrumb.Separator>
  </Breadcrumb>
Dropdown
<Dropdown 
   overlay={
    封装的Menu组件 }
   // 弹框显示一个箭头
   arrow
   // 菜单弹出位置
   placement="bottomLeft"
   // 触发方式 contextMenu 鼠标右键触发
   trigger={
   ['click'|'hover|contextMenu']}
   
>
   <Button>这是按钮</Button>
</Dropdown>
Menu
// SubMenu 对 menuitem 进行分组
<Menu 
   mode='horizontal|vertical|inline'
   theme="dark|light"
   // 控制整体展开 还是 只显示一个图标
   inlineCollapsed={
   true | false} 
   inlineIndent={
   number} 缩进的宽度
   // 默认展开项 选中项
   defaultSelectedKeys={
   ['MenuItemKeys']}
   defaultOpenKeys={
   ['SubMenuKeys']}
   // 当前展开的 SubMenu 菜单 keys 数组
   openKeys={
   ['SubMenuKeys']}
   // 展开事件 可以通过这个控制 同时只显示一个子菜单
   onOpenChange={
   (openKeys)=>string[]}
>
  <SubMenu
    key='SubMenu'
    icon
    title
  > 
    // ItemGroup 会在侧边栏上显示一个标题 没有其他效果
    <ItemGroup
      key=''
      title=''
    >
       <MenuItem
          key=''
          icon
       >
          这是子菜单
       </MenuItem>
    </ItemGroup>
  </SubMenu>
</Menu>
PageHeader
Pagination
# 逻辑
当前页面 一页放几条数据 总共多少数据  当前页码
 pageSize total current
当点击的时候 将点击的页码切换
通过当前页面 发起网络请求 覆盖数据
#
<Pagination
  pageSize={
   每页条数}
  total={
   数据总数}
  current={
   当前页数}
  // 按钮控制 一页显示多少条、
  pageSizeOptions=[]
  onChange={
   (page,pageSize)=> }
  showTotal: (total) => `${
     total} 条数据`,
  defaultPageSize
  defaultCurrent
/>
    
# 页码重置问题
    https://stackoverflow.com/questions/69638994/how-to-reset-the-paginations-current-page-when-pagesize-changes-in-ant-design
Steps
<Steps
  // 控制高亮位置
  current={
   1} 
  size='small'
>
  <Step
     title
     subTitle
     description
     status="finish|process|wait"
     icon
  >
  </Step>
</Steps>

数据录入

AutoComplete
#
 <AutoComplete
   placeholder
   style
   
   // 数据源
   options
   //  当前选择条目
   value
   
   onSelect
   onSearch
   onChange
   showSearch={
   {
    filter }}
 />
	filter(inputValue, path) {
   
			return path.some(option => option.name.indexOf(inputValue) > -1);
		},
     
DatePicker
import moment from 'moment'
// 时间选择器
import {
    DatePicker } from 'antd'; 
// 时间范围选择器
const {
    RangePicker } = DatePicker; 
// 中文需要的包
import 'moment/locale/zh-cn';
import locale from 'antd/es/date-picker/locale/zh_CN';

<RangePicker 
## 基础配置
  // 禁用组件
  disabled={
   [false,true]}
  // 页脚内容
  renderExtraFooter={
   () => 'extra footer'}
  // 无边框
  bordered={
   false}
  size={
   'large|miaddle|small'}
  // 中文 需要引入 moment中文 和 时间选择器中文 的包
  locale={
   locale}

## 具体时间配置
  // 当是范围选择器的时候 必须开启这个 配合 Onchange
  value={
   ""}
  // 点击后 限制时间类型
  picker="year|quarter|month|week|date|time"
  // 点击后开启具体 时分秒选择器
  showTime={
   {
    
      format: "hh[时]mm[分]ss[秒]",
      defaultValue:[ 
            // 设置时分秒默认值 不选择时分秒就是默认的
            moment('01:00:00', 'HH:mm:ss'),
            moment('11:59:59', 'HH:mm:ss')
          ]
     }}
  // 默认一点击就显示的时间范围 不写就从最新时间开始 
  搭配 showTime 使用
  defaultPickerValue={
   moment("2021-05-01")}
  // 不点击时显示的时间格式过滤
  format="YYYY/MM/DD HH:mm:ss"
  // 自定义快捷时间按钮设置 showToday={false}
  ranges={
   {
   
     Today: [moment(), moment()],
     '当月':[ 
         moment().startOf('month'),
         moment().endOf('month') 
        ]
     }}
  // 自定义每个日期的外观
  dateRender={
   current => {
   
      const style = {
   };
      if (current.date() === 1) {
   
            style.border = '1px solid #1890ff';
            style.borderRadius = '50%';
      }
      return (   
         <div className="ant-picker-cell-inner" style={
   style}>
              {
   current.date()}
         </div>
          )
   }}
  // 禁用限制 时间   具体见下面的 demo
  disabledDate={
   disabledDate} 

## 事件
/* 时间改变的事件 参数是改变的时间 
  当为 datepicker 时候 不能取消同一时间 需要设置 value={''}才行
*/
  onChange={
   (date:moment,dateString:string)=>}
  // 待选日期变化回调 用于时间范围限制7天时间
  onCalendarChange={
   val => setDates((val))}
/>
禁用年月日时分秒
## 禁用 年月日 时分秒 => 限制时间选择范围、
// 需要开启 showTime 来限制时分秒
<RangePicker
    defaultPickerValue={
   moment("2021-05-01")}
    showTime={
   {
   format: "hh时mm分ss秒"}}
    // 限制年月日
    disabledDate={
   disabledDate}
    // 限制时分秒
    disabledTime={
   disabledTime}
/>
      
 const disabledDate = (currentDate) => {
   
    const start = moment("2021-05-01")
    const end = moment("2021-06-01")
// 将时间限制在 只能选择2021年 5到6月 的时间
    return currentDate && currentDate < start
           || currentDate > end
// 将时间限制在 只能选择 除了 202105-202106 之外任意时间
    return currentDate && !(currentDate < start
           || currentDate > end)
 // 时间最早是8天前
   return current && current < moment().subtract(8, 'day');
  }
 
 // 工具函数 拿到范围内的数组
 function range(start, end) {
   const result = [];
 for (let i = start; i < end; i++) {
    result.push(i);
 }return result;}
const disabledTime = () => {
   
  return {
   
    // 只能选择 4-24  小时
    disabledHours: () => range(0, 24).splice(4, 20),
    // 只能选择 00-29 分钟
    disabledMinutes: () => range(30, 60), 
    // 只能选择 除了55 56 秒的 秒数
    disabledSeconds: () => [55, 56],  
    }
  }
禁用7天范围
# 禁用7天范围
<RangePicker
    defaultPickerValue={
   moment("2021-05-01")}
    showTime={
   {
   format: "hh时mm分ss秒"}}
    disabledDate={
   disabledDate}
    onCalendarChange={
   val => setDates((val))}
/>
   const [dates, setDates] = useState([]);

   const disabledDate = (current) => {
   
// 限制 7天以内
    if (!dates || dates.length === 0) {
   return false;}
const tooLate = dates[0] && current.diff(dates[0],'days') > 7;
const tooEarly=dates[1] && dates[1].diff(current, 'days') > 7;
 return tooEarly || tooLate;
// 2021-05-01至2021-06-01 && 7天以内
     if (!dates || dates.length === 0) {
   return false;}
     const start = moment("2021-05-01")
     const end = moment("2021-06-01")
const tooLate=dates[0] && current.diff(dates[0], 'days') > 7;
const tooEarly=dates[1]&&(dates[1]).diff(current, 'days') > 7;
     return  current && (tooEarly || tooLate) 
             || current < start || current > end
  };
禁用年份
  • 需要升级最新版
  • “ant-design-vue”: “^1.7.8”,
 <DatePicker format="YYYY" disabledDate={
   disabledYear} />
   
 function disabledYear(current) {
   
  return current.year() === 2021; // disabling 2021
  // return current.year() !== 2021; // disabling everything besides 2021
  // return current.year() !== (new Date).getFullYear(); // disabling everything besides current year
  // return current.year() > 2021; // disabling everything further than 2021
  // return current.year() < 2021; // disabling everything in the past before 2021
  // return [2018, 2019].includes(current.year()); // disabling 2018 and 2019
}
demo
import {
    useState } from 'react'
import {
    DatePicker } from 'antd';
import 'moment/locale/zh-cn';
import locale from 'antd/es/date-picker/locale/zh_CN';
import moment from 'moment'

const {
    RangePicker } = DatePicker;

const Test = () => {
   
  const [dates, setDates] = useState([]);

  // 1.1 将时间限制在 只能选择2021年 5到6月 的时间
  // const disabledDate = (currentDate) => {
   
  //   const start = moment("2021-05-01")
  //   const end = moment("2021-06-01")
  //   return currentDate && currentDate < start
  //     || currentDate > end
  // }

  // 1.2 将时间限制在 只能选择 除了 202105-202106 之外任意时间
  // const disabledDate = (currentDate) => {
   
  //   const start = moment("2021-05-01")
  //   const end = moment("2021-06-01")
  //   return currentDate && !(currentDate < start
  //     || currentDate > end)
  // }

  // 1.3 限制7天之内
  // const disabledDate = (current) => {
   
  //   if (!dates || dates.length === 0) { return false; }
  //   const tooLate = dates[0] && current.diff(dates[0], 'days') > 7;
  //   const tooEarly = dates[1] && dates[1].diff(current, 'days') > 7;
  //   return tooEarly || tooLate;
  // };

  // 1.4 限制 2021-05-01至2021-06-01 && 7天以内
  const disabledDate = (current) => {
   
    if (!dates || dates.length === 0) {
    return false; }
    const start = moment("2021-05-01")
    const end = moment("2021-06-01")
    const tooLate = dates[0] && current.diff(dates[0], 'days') > 7;
    const tooEarly = dates[1] && (dates[1]).diff(current, 'days') > 7;
    return current && (tooEarly || tooLate)
      || current < start || current > end
  };

  // 工具函数 拿到范围内的数组
  function range(start, end) {
   
    const result = [];
    for (let i = start; i < end; i++) {
   
      result.push(i);
    } return result;
  }
  // 2.1 限制时分秒
  const disabledTime = () => {
   
    return {
   
      // 只能选择 4-24  小时
      disabledHours: () => range(0, 24).splice(4, 20),
      // 只能选择 00-29 分钟
      disabledMinutes: () => range(30, 60),
      // 只能选择 除了55 56 秒的 秒数
      disabledSeconds: () => [55, 56],
    }
  }
  return (
    <>
      <RangePicker
        // disabled={[false, true]}
        renderExtraFooter={
   () => '这是页脚'}
        bordered={
   false}
        size={
   'large'}
        locale={
   locale}
        // picker="year|quarter|month|week|date|time"
        showTime={
   {
   
          format: "hh时mm分ss秒",
          defaultValue: [
            moment('01:00:00', 'HH:mm:ss'),
            moment('11:59:59', 'HH:mm:ss')
          ]
        }}
        defaultPickerValue={
   moment("2021-05-01")}
        format="YYYY/MM/DD HH:mm:ss"
        ranges={
   {
   
          Today: [moment(), moment()],
          '当月': [
            moment().startOf('month'),
            moment().endOf('month')
          ]
        }}
        dateRender={
   current => {
   
          const style = {
   };
          if (current.date() === 1) {
   
            style.border = '1px solid #1890ff';
            style.borderRadius = '50%';
           }
          return (   
         <div className="ant-picker-cell-inner" style={
   style}>
              {
   current.date()}
            </div>
           )
         }}
        disabledDate={
   disabledDate}
        // disabledTime={disabledTime}
        onCalendarChange={
   val => setDates((val))}
        onChange={
   (date, dateString) => console.log(date, dateString)}
      />
    </>
  )
}
export default Test
选中多个日期
# 
import React, {
    useState } from "react";
import {
    DatePicker, Button } from "antd";
import moment from "moment";
import styles from './index.less';

const MultipleDatePicker = () => {
   
  // 选中的日期 timestamp[]
  const [selectedDate, setSelectedDate] = useState([])

  // 日期发生变化时 重复去重 没有则添加
  const onValueChange = (date) => {
   
    const newDate = moment(date).startOf("day").valueOf()
    if (selectedDate.includes(newDate)) {
   
      setSelectedDate([...selectedDate.filter(item => item !== newDate)])
    } else {
   
      setSelectedDate([...selectedDate, newDate])
    }
  };

  // 渲染选中日期外观
  const dateRender = (currentDate) => {
   
    const isSelected = selectedDate.includes(moment(currentDate).startOf("day").valueOf())
    let selectStyle = isSelected ?
      {
   
        position: 'relative',
        zIndex: 2,
        display: 'inlineBlock',
        width: "24px",
        height: "22px",
        lineHeight: "22px",
        backgroundColor: "#1890ff",
        color: "#fff",
        margin: "auto",
        borderRadius: "2px",
        transition: "background 0.3s, border 0.3s"
      }
      : {
   }
    return (<div style={
   selectStyle} > {
   currentDate.date()}  </div >)
  }

  return (
    <>
      <div className={
   styles.multipleDatePicker}>
        <DatePicker
          open
          dateRender={
   dateRender
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值