Ant Design时间组件详解:日期选择器与日历功能实现

Ant Design时间组件详解:日期选择器与日历功能实现

【免费下载链接】ant-design An enterprise-class UI design language and React UI library 【免费下载链接】ant-design 项目地址: https://gitcode.com/gh_mirrors/ant/ant-design

组件概述

Ant Design提供了丰富的时间处理组件,主要包括日期选择框(DatePicker)和日历(Calendar)两大类。这些组件基于dayjs库开发,支持多种日期格式和交互方式,能够满足企业级应用的各种时间选择需求。

日期选择框组件位于components/date-picker目录下,提供了日期、时间、月份、年份等多种选择模式。日历组件位于components/calendar目录下,主要用于按日历形式展示数据。

日期选择器(DatePicker)详解

基本使用

日期选择器的基础用法非常简单,导入组件后直接使用即可:

import { DatePicker } from 'antd';
import dayjs from 'dayjs';

function App() {
  return <DatePicker defaultValue={dayjs('2023-01-01')} />;
}

这个例子展示了最基本的日期选择器,用户可以点击输入框弹出日期面板进行选择。默认情况下,组件会显示当前日期,并允许用户选择任意日期。

核心功能

1. 多种选择模式

DatePicker提供了多种选择模式,可以通过picker属性进行配置:

// 日期选择
<DatePicker picker="date" />

// 月份选择
<DatePicker picker="month" />

// 年份选择
<DatePicker picker="year" />

// 季度选择 (4.1.0 新增)
<DatePicker picker="quarter" />

// 周选择
<DatePicker picker="week" />

这些不同的选择模式对应着不同的业务场景,例如选择生日可以使用日期模式,选择财政季度可以使用季度模式。

2. 范围选择

RangePicker允许用户选择一个日期范围,非常适合需要选择开始和结束日期的场景:

import { DatePicker } from 'antd';

const { RangePicker } = DatePicker;

function App() {
  return <RangePicker />;
}

范围选择器默认会显示两个输入框,分别对应开始日期和结束日期。用户可以通过预设范围快速选择常用的日期范围,如最近7天、最近30天等。

3. 日期格式自定义

可以通过format属性自定义日期的显示格式,配置参考dayjs#format

<DatePicker format="YYYY/MM/DD" />
<DatePicker format="YYYY年MM月DD日" />
<RangePicker format={['YYYY-MM-DD', 'YYYY-MM-DD']} />
4. 禁用日期和时间

通过disabledDatedisabledTime属性可以禁用特定的日期和时间:

// 禁用今天之前的日期
<DatePicker
  disabledDate={(current) => current && current < dayjs().startOf('day')}
/>

// 禁用特定时间
<DatePicker
  showTime
  disabledTime={() => ({
    disabledHours: () => [0, 1, 2, 3, 4, 5, 6, 7, 22, 23],
  })}
/>

高级功能

1. 时间选择

通过设置showTime属性,可以在日期选择器中添加时间选择功能:

<DatePicker showTime />

这在需要精确到小时、分钟的场景中非常有用,如会议安排、航班预订等。

2. 预设范围

使用presets属性可以添加预设的日期范围,方便用户快速选择常用的日期范围:

<RangePicker
  presets={[
    { label: '今天', value: [dayjs(), dayjs()] },
    { label: '昨天', value: [dayjs().subtract(1, 'day'), dayjs().subtract(1, 'day')] },
    { label: '近7天', value: [dayjs().subtract(6, 'day'), dayjs()] },
  ]}
/>
3. 自定义单元格

从5.4.0版本开始,可以使用cellRender属性自定义日期单元格的内容:

<DatePicker
  cellRender={(current, info) => {
    // 为每月1号添加特殊标记
    if (current.date() === 1) {
      return (
        <div>
          <span>{current.date()}</span>
          <span style={{ color: 'red', fontSize: '12px' }}>月初</span>
        </div>
      );
    }
    return info.originNode;
  }}
/>

这个功能可以用于突出显示特殊日期,如节假日、重要事件等。

API参考

日期选择器的完整API可以在components/date-picker/index.zh-CN.md中查看。主要属性包括:

参数说明类型默认值
defaultValue默认日期dayjs-
value日期dayjs-
format日期格式string'YYYY-MM-DD'
disabled是否禁用booleanfalse
disabledDate不可选择的日期function(currentDate)-
showTime是否显示时间选择booleanfalse
picker选择器类型'date' | 'week' | 'month' | 'quarter' | 'year''date'
onChange日期变化回调function(date, dateString)-

日历(Calendar)详解

基本使用

日历组件的基本用法如下:

import { Calendar } from 'antd';

function onSelect(date) {
  console.log('Selected date:', date);
}

function App() {
  return <Calendar onSelect={onSelect} />;
}

默认情况下,日历会全屏显示,用户可以点击日期进行选择,也可以通过顶部的导航切换月份和年份。

核心功能

1. 自定义单元格

使用cellRender属性可以自定义日历单元格的内容:

<Calendar
  cellRender={(current, today, info) => {
    // 为今天添加特殊样式
    if (current.isSame(today, 'day')) {
      return (
        <div style={{ backgroundColor: '#e6f7ff', borderRadius: '50%', width: '24px', height: '24px', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto' }}>
          {current.date()}
        </div>
      );
    }
    return info.originNode;
  }}
/>
2. 通知事项日历

日历组件非常适合展示日程安排等信息:

function App() {
  const events = [
    { date: '2023-06-12', title: '团队会议' },
    { date: '2023-06-15', title: '项目截止' },
    { date: '2023-06-20', title: '产品发布' },
  ];

  return (
    <Calendar
      cellRender={(current) => {
        const event = events.find(e => current.isSame(e.date, 'day'));
        if (event) {
          return (
            <div>
              <span>{current.date()}</span>
              <div style={{ fontSize: '12px', color: '#1890ff' }}>{event.title}</div>
            </div>
          );
        }
        return current.date();
      }}
    />
  );
}
3. 选择功能

通过onSelect回调函数可以获取用户选择的日期:

<Calendar
  onSelect={(date, { source }) => {
    if (source === 'date') {
      console.log('用户选择了日期:', date.format('YYYY-MM-DD'));
    }
  }}
/>

source参数可以判断选择的来源,可能的值包括'year'、'month'、'date'和'customize'。

高级用法

1. 卡片模式

设置fullscreen属性为false可以将日历显示为卡片模式,适合嵌入到其他容器中:

<Calendar fullscreen={false} />
2. 自定义头部

使用headerRender属性可以自定义日历的头部内容:

<Calendar
  headerRender={({ value, type, onChange, onTypeChange }) => {
    return (
      <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
        <button onClick={() => onChange(value.subtract(1, type))}>上月</button>
        <h3 style={{ margin: '0 16px' }}>{value.format(type === 'month' ? 'YYYY年MM月' : 'YYYY年')}</h3>
        <button onClick={() => onChange(value.add(1, type))}>下月</button>
        <button onClick={() => onTypeChange(type === 'month' ? 'year' : 'month')} style={{ marginLeft: '16px' }}>
          {type === 'month' ? '切换到年视图' : '切换到月视图'}
        </button>
      </div>
    );
  }}
/>
3. 农历支持

日历组件支持农历显示,只需引入相应的dayjs插件:

import dayjs from 'dayjs';
import农历 from 'dayjs/plugin/lunar';

dayjs.extend(农历);

<Calendar
  cellRender={(current) => {
    return (
      <div style={{ textAlign: 'center' }}>
        <div>{current.date()}</div>
        <div style={{ fontSize: '12px', color: '#999' }}>{current.lunar().format('MM-DD')}</div>
      </div>
    );
  }}
/>

API参考

日历组件的完整API可以在components/calendar/index.zh-CN.md中查看。主要属性包括:

参数说明类型默认值
defaultValue默认展示的日期dayjs-
value展示日期dayjs-
fullscreen是否全屏显示booleantrue
cellRender自定义单元格内容function(current, today, info)-
onSelect选择日期回调function(date, info)-
onPanelChange日期面板变化回调function(date, mode)-
mode初始模式'month' | 'year''month'

实际应用案例

1. 酒店预订日期选择

import { DatePicker, Card, Typography } from 'antd';
import { CalendarOutlined } from '@ant-design/icons';
import dayjs from 'dayjs';

const { RangePicker } = DatePicker;
const { Title, Text } = Typography;

function HotelBooking() {
  const [range, setRange] = useState([
    dayjs().add(1, 'day'),
    dayjs().add(3, 'day'),
  ]);
  
  const disabledDate = (current) => {
    // 禁用今天及之前的日期
    return current && current < dayjs().endOf('day');
  };
  
  return (
    <Card title="酒店预订" bordered={false}>
      <Title level={5}>选择入住和退房日期</Title>
      <RangePicker
        disabledDate={disabledDate}
        defaultValue={range}
        onChange={setRange}
        format="YYYY-MM-DD"
        renderExtraFooter={() => (
          <div style={{ textAlign: 'center', padding: '16px' }}>
            <Text type="secondary">
              {range && range[0] && range[1] 
                ? `共 ${range[1].diff(range[0], 'day')} 晚` 
                : '请选择日期范围'}
            </Text>
          </div>
        )}
        placeholder={['入住日期', '退房日期']}
        suffixIcon={<CalendarOutlined />}
      />
    </Card>
  );
}

这个案例展示了如何使用RangePicker实现酒店预订的日期选择功能,包括禁用过去的日期、显示入住天数等功能。

2. 日程安排日历

import { Calendar, Badge, Popover } from 'antd';
import { ClockCircleOutlined, CoffeeOutlined, MeetingOutlined } from '@ant-design/icons';
import dayjs from 'dayjs';

// 模拟日程数据
const scheduleData = {
  '2023-06-10': [
    { time: '09:00', title: '团队例会', type: 'meeting' },
    { time: '14:30', title: '项目评审', type: 'meeting' },
  ],
  '2023-06-15': [
    { time: '10:00', title: '客户拜访', type: 'business' },
  ],
  '2023-06-20': [
    { time: '12:00', title: '午餐会议', type: 'lunch' },
    { time: '15:00', title: '技术分享', type: 'meeting' },
  ],
};

function ScheduleCalendar() {
  const getEventIcon = (type) => {
    switch (type) {
      case 'meeting':
        return <MeetingOutlined style={{ color: '#1890ff' }} />;
      case 'business':
        return <ClockCircleOutlined style={{ color: '#fa8c16' }} />;
      case 'lunch':
        return <CoffeeOutlined style={{ color: '#52c41a' }} />;
      default:
        return <ClockCircleOutlined />;
    }
  };
  
  return (
    <Calendar
      cellRender={(current, today, info) => {
        const dateStr = current.format('YYYY-MM-DD');
        const events = scheduleData[dateStr];
        
        if (events && events.length > 0) {
          const content = (
            <div>
              {events.map((event, index) => (
                <div key={index} style={{ marginBottom: '8px' }}>
                  <Badge status="processing" text={
                    <span>
                      {getEventIcon(event.type)}
                      <span style={{ marginLeft: '8px' }}>{event.time} {event.title}</span>
                    </span>
                  } />
                </div>
              ))}
            </div>
          );
          
          return (
            <Popover content={content} placement="top" trigger="hover">
              <div>
                <span>{current.date()}</span>
                <div style={{ marginTop: '4px' }}>
                  {events.slice(0, 2).map((event, index) => (
                    <div key={index} style={{ fontSize: '12px', color: '#1890ff', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      {event.title}
                    </div>
                  ))}
                  {events.length > 2 && <div style={{ fontSize: '12px', color: '#999' }}>+{events.length - 2} 更多</div>}
                </div>
              </div>
            </Popover>
          );
        }
        
        return info.originNode;
      }}
    />
  );
}

这个案例展示了如何使用Calendar组件实现一个日程安排功能,包括自定义单元格显示、悬停查看详情等功能。

国际化配置

Ant Design的时间组件默认使用en-US语言,如需设置其他语言,可以使用ConfigProvider进行全局配置:

import { ConfigProvider, DatePicker, Calendar } from 'antd';
import zhCN from 'antd/locale/zh_CN';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';

dayjs.locale('zh-cn');

function App() {
  return (
    <ConfigProvider locale={zhCN}>
      <DatePicker />
      <Calendar />
    </ConfigProvider>
  );
}

更多国际化配置细节可以参考ConfigProvider 国际化文档。

常见问题解决

1. 日期格式转换问题

使用dayjs可以轻松处理各种日期格式转换:

// 字符串转dayjs对象
const date = dayjs('2023-01-01', 'YYYY-MM-DD');

// dayjs对象转字符串
const dateStr = date.format('YYYY年MM月DD日');

2. 时间选择器国际化不生效

确保正确导入并配置了dayjs的locale:

import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';

dayjs.locale('zh-cn');

3. 限制日期选择范围

使用disabledDate属性可以限制可选日期范围:

// 只允许选择今天之后7天内的日期
<DatePicker
  disabledDate={(current) => {
    const today = dayjs();
    const sevenDaysLater = today.add(7, 'day');
    return current < today.startOf('day') || current > sevenDaysLater.endOf('day');
  }}
/>

4. 表单中的日期验证

在Form组件中使用日期选择器时,可以添加自定义验证规则:

<Form.Item
  name="birthday"
  label="出生日期"
  rules={[
    { required: true, message: '请选择出生日期' },
    { 
      validator: (_, value) => {
        if (value && value > dayjs().subtract(18, 'year')) {
          return Promise.reject('必须年满18周岁');
        }
        return Promise.resolve();
      }
    }
  ]}
>
  <DatePicker format="YYYY-MM-DD" />
</Form.Item>

总结

Ant Design的时间组件提供了强大而灵活的日期和时间处理能力,无论是简单的日期选择还是复杂的日程安排,都能满足各种业务需求。通过本文的介绍,我们了解了DatePicker和Calendar组件的基本用法、核心功能和高级特性,以及如何在实际项目中应用这些组件。

要深入了解更多细节,可以查阅官方文档:

掌握这些时间组件的使用,将有助于我们构建更加用户友好和功能完善的企业级应用。

【免费下载链接】ant-design An enterprise-class UI design language and React UI library 【免费下载链接】ant-design 项目地址: https://gitcode.com/gh_mirrors/ant/ant-design

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值