工作中制造的一个react日历轮子

Posted lzhflzjx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工作中制造的一个react日历轮子相关的知识,希望对你有一定的参考价值。

需求需要在日历上实现多选但不连续的日期,ant design 的日历组件只能单选或者连续选择一段日期

附上代码----主代码部分

import React, { Component } from "react";
import { routerRedux } from "dva/router";
import { connect } from "dva";
import {
  Menu,
  Icon,
  Form,
  Select,
  Row,
  Col,
  Card,
  Button,
  message,
  TimePicker,
  InputNumber,
} from "antd";
import moment from "moment";
// import ‘./ReserveList1.css‘;
import styles from "./ReserveList1.less";

import PageHeaderWrapper from "@/components/PageHeaderWrapper";

const { Option } = Select;
const FormItem = Form.Item;
// console.log(moment);
const DATE_FORMAT = "YYYY-MM-DD";

const holidayMap = {
  // "2019-05-01": "劳动节221",
  // "2019-05-02": "劳动节2",
  // "2019-05-03": "劳动节3",
  // "2019-05-04": "五四青年节",
  // "2019-06-07": "端午节1",
  // "2019-06-08": "端午节2",
  // "2019-06-09": "端午节3",
  // "2020-07-09": "已预约",
  // "2020-07-10": "已预约",
};
// 后台返回的已预约的日期
let reverMap = [
  // { subscribeDate: "2020-07-01" },
  // { subscribeDate: "2020-07-02" },
  // { subscribeDate: "2020-07-03" },
  // { subscribeDate: "2020-07-04" },
];
// 点击已选择的日期
let reverParam = [];

class queryForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      options: {
        years: [],
        months: [],
      },
    };
  }

  state = {};

  componentDidMount = function() {
    let mySelf = this;
    reverParam = [];
    mySelf.init();
  };

  init = () => {
    let mySelf = this;
    mySelf.initOptions();
    mySelf.setDefaultOption();
  };

  initOptions = function() {
    let mySelf = this;
    let options = mySelf.state.options;
    let now = moment();
    const yearOfNow = now.year();
    let yearsOptions = [];
    let monthsOptions = [];
    // const startYear = yearOfNow - 20;
    const startYear = yearOfNow;
    const endYear = yearOfNow + 10;
    const startMonth = 1;
    const endMonth = 12;

    for (let i = startYear; i < endYear; i++) {
      let item = {
        key: i,
        label: i,
      };
      yearsOptions.push(item);
    }

    for (let i = startMonth; i <= endMonth; i++) {
      let item = {
        key: i,
        label: i,
      };
      monthsOptions.push(item);
    }

    // console.log(platformOptions);
    options.years = yearsOptions;
    options.months = monthsOptions;
    mySelf.setState({
      options: options,
    });
  };

  setDefaultOption = () => {
    let mySelf = this;
    let form = mySelf.props.form;
    // let options = mySelf.state.options;
    let now = moment();
    const yearOfNow = now.year();
    const monthOfNow = now.month() + 1;

    // console.log(options);
    let defaultYearOption = { key: yearOfNow, label: yearOfNow };
    let defaultMonthOption = { key: monthOfNow, label: monthOfNow };
    // console.log(defaultOption)
    let formData = {
      year: defaultYearOption,
      month: defaultMonthOption,
    };
    form.setFieldsValue(formData);
  };

  changeMonth = (pars, nowMonth) => {
    let mySelf = this;
    let form = mySelf.props.form;
    let res = form.getFieldsValue();
    let month = Number(res.month.key) + Number(pars);
    if (nowMonth == "当月") {
      let now = moment();
      const yearOfNow = now.year();
      const monthOfNow = now.month() + 1;
      month = monthOfNow;
      let monthOption = { key: month, label: month };
      let yearOption = { key: yearOfNow, label: yearOfNow };
      // console.log(monthOption);
      let formData = {
        month: monthOption,
        year: yearOption,
      };
      form.setFieldsValue(formData);
      mySelf.props.changeCalendar();
      this.setState({
        disableNext: false,
        disablePre: false,
      });
      return
    }
    if (month <= 0 && pars < 0) {
      this.setState({
        disablePre: true,
      });
      return;
    } else {
      this.setState({
        disablePre: false,
      });
    }
    if (month >= 13 && pars > 0) {
      this.setState({
        disableNext: true,
      });
      return;
    } else {
      this.setState({
        disableNext: false,
      });
    }
    let monthOption = { key: month, label: month };
    // console.log(monthOption);
    let formData = {
      month: monthOption,
    };
    form.setFieldsValue(formData);
    mySelf.props.changeCalendar();
  };

  render() {
    let mySelf = this;
    // eslint-disable-next-line
    let { getFieldDecorator, getFieldValue } = mySelf.props.form;
    let { options, disablePre, disableNext } = mySelf.state;
    // console.log(options);
    return (
      <div>
        <Row className="margin-bottom-5">
          <Col span={24}>
            <Form
              layout="inline"
              // wrappedComponentRef={(inst) => this.queryForm = inst}
            >
              <FormItem label="年">
                {getFieldDecorator("year", {})(
                  <Select
                    labelInValue
                    size={"default"}
                    placeholder="year"
                    style={{ width: 150 }}
                    onChange={() =>
                      setTimeout(() => {
                        mySelf.props.changeCalendar();
                      }, 0)
                    }
                  >
                    {options.years.map(function(item, index) {
                      return <Option key={item.key}>{item.label}</Option>;
                    })}
                  </Select>
                )}
              </FormItem>
              <FormItem label="月">
                {getFieldDecorator("month", {})(
                  <Select
                    labelInValue
                    size={"default"}
                    placeholder="month"
                    style={{ width: 150 }}
                    onChange={() =>
                      setTimeout(() => {
                        mySelf.props.changeCalendar();
                      }, 0)
                    }
                  >
                    {options.months.map(function(item, index) {
                      return <Option key={item.key}>{item.label}</Option>;
                    })}
                  </Select>
                )}
              </FormItem>
              <FormItem>
                <Button
                  type="primary"
                  size="small"
                  onClick={() => mySelf.changeMonth(-1)}
                  disabled={disablePre}
                >
                  上个月
                </Button>

                <Button
                  type="primary"
                  size="small"
                  onClick={() => mySelf.changeMonth(1)}
                  className={styles["margin-left-5"]}
                  disabled={disableNext}
                >
                  下个月
                </Button>
                <Button
                  type="primary"
                  size="small"
                  onClick={() => mySelf.changeMonth(0,"当月")}
                  className={styles["margin-left-5"]}
                >
                  今天
                </Button>
              </FormItem>
            </Form>
          </Col>
        </Row>
      </div>
    );
  }
}
let QueryFormComponent = Form.create()(queryForm);
class queryForm1 extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      subscribeTimeObj: {
        subscribeTimeList: [0],
      },
      disablePre: false,
      disableNext: false,
    };
  }

  state = {};

  componentDidMount = function() {
    let mySelf = this;
  };

  addSubscribeTimeList = () => {
    let s = this.state.subscribeTimeObj.subscribeTimeList;
    s[s.length] = s.length;
    this.setState({
      subscribeTimeObj: Object.assign(
        {},
        {
          subscribeTimeList: s,
        }
      ),
    });
  };

  delSubscribeTimeList = (idx) => {
    let s = this.state.subscribeTimeObj.subscribeTimeList;
    if (s.length > 1) {
      s.splice(idx, 1);
      this.setState({
        subscribeTimeObj: Object.assign(
          {},
          {
            subscribeTimeList: s,
          }
        ),
      });
    }
  };

  render() {
    let mySelf = this;
    // eslint-disable-next-line
    let { getFieldDecorator, getFieldValue } = mySelf.props.form;
    let { subscribeTimeObj } = mySelf.state;
    // console.log(options);
    return (
      <div>
        <Button
          className={styles.timeAddButton}
          type="primary"
          onClick={() => mySelf.addSubscribeTimeList()}
        >
          添加
        </Button>
        <div className={styles.timeSlotWrap}>
          {subscribeTimeObj.subscribeTimeList.map((_, idx) => (
            <Row key={idx} gutter={{ md: 8 }}>
              <Col md={8} sm={8}>
                <FormItem
                  key={"subscribeStartTime" + idx}
                  label=""
                  labelCol={{ span: 6 }}
                  wrapperCol={{ span: 24 }}
                >
                  {getFieldDecorator("data[" + idx + "].subscribeStartTime", {
                    rules: [{ required: true, message: "请选择开始时间!" }],
                  })(<TimePicker style={{ width: "100%" }} format={"HH:mm"} />)}
                </FormItem>
              </Col>
              <Col md={8} sm={8}>
                <FormItem
                  key={"subscribeEndTime" + idx}
                  label=""
                  labelCol={{ span: 6 }}
                  wrapperCol={{ span: 24 }}
                >
                  {getFieldDecorator("data[" + idx + "].subscribeEndTime", {
                    rules: [{ required: true, message: "请选择结束时间!" }],
                  })(<TimePicker style={{ width: "100%" }} format={"HH:mm"} />)}
                </FormItem>
              </Col>
              <Col md={6} sm={6}>
                <FormItem
                  key={"subscribeCount" + idx}
                  labelCol={{ span: 6 }}
                  wrapperCol={{ span: 24 }}
                  label=""
                >
                  {getFieldDecorator("data[" + idx + "].subscribeCount", {
                    rules: [{ required: true, message: "请输入数量!" }],
                  })(
                    <InputNumber
                      style={{ width: "100%" }}
                      min={1}
                      step={1}
                      placeholder="可预约数量"
                    />
                  )}
                </FormItem>
              </Col>
              <Col style={{ padding: "9px" }} md={2} sm={2}>
                <Icon
                  onClick={() => mySelf.delSubscribeTimeList(idx)}
                  type="close"
                />
              </Col>
            </Row>
          ))}
        </div>
      </div>
    );
  }
}
let QueryFormComponent1 = Form.create()(queryForm1);

@connect(({ reservelist1, loading, global }) => ({
  global,
  reservelist1,
  loading: loading.models.reservelist1,
}))
class LeCalendar extends Component {
  constructor(props) {
    super(props);
    this.state = {
      //渲染日历过程中,当前显示月的moment对象
      monthDisplay: "",
      dates: [[], []],
    };
  }

  componentDidMount = () => {
    let mySelf = this;
    mySelf.init();
    mySelf.generateDates();
  };

  init = () => {
    let mySelf = this;
    mySelf.changeCalendar();
    let todayDate = moment().format("YYYY-MM-DD");
    mySelf.toSetScribeDefaultValue({
      pageIndex: 1,
      pageSize: 100,
      startTime: todayDate,
      endTime: "2029-12-31",
    });
  };

  toSetScribeDefaultValue = async (params, cb) => {
    const { dispatch, account } = this.props;
    await dispatch({
      type: "reservelist1/fetch1",
      payload: params,
      callback: (s, m, data) => {
        const {
          data: { list },
        } = s;
        let array = [];
        list.forEach((e) => {
          array.push({ subscribeDate: e.subscribeDate });
        });

        // reverMap = Array.from(new Set(array));
        reverMap = array;

        let mySelf = this;
        mySelf.generateDates();
        cb && cb(s, m, data);
      },
    });
  };

  generateDates = (reserveDate) => {
    let mySelf = this;
    let dates = [];
    //单个日历,显示6周
    const weeksNum = 6;
    //每周显示7天
    const weekDaysNum = 7;
    //日历中的今天
    const todayDate = moment().format(DATE_FORMAT);
    //渲染日历过程中,当前显示月的moment对象
    let now = mySelf.state.monthDisplay;
    //当前显示的月份
    let nowMonth = now.month();
    // console.log(nowMonth);
    //当月第一天
    let firstDayOfMonth = now.clone().startOf("month");
    //当月第一天是星期几
    let weekOfFirstDay = firstDayOfMonth.isoWeekday();
    //日历上的当月显示的第一天
    let firstDayOfMonthDisplay = firstDayOfMonth
      .clone()
      .subtract(weekOfFirstDay - 1, "days");

    //渲染日历过程中,使用的当前moment对象
    let currentDate = firstDayOfMonthDisplay.clone();
    // console.log(firstDayOfMonthDisplay.format(DATE_FORMAT));
    const otherMonthClass = "other-month";
    const dayOffClass = "day-off";
    const holidayClass = "holiday";
    const todayClass = "today";
    const lastClass = "lastDay";
    const reserveClass = "reservation";
    const selectClass = "selected";

    for (let i = 0; i < weeksNum; i++) {
      let weekList = [];
      for (let j = 0; j < weekDaysNum; j++) {
        let date = currentDate.format(DATE_FORMAT);
        let dateDisplay = currentDate.date();
        let currentMonth = currentDate.month();
        let currentWeekDay = currentDate.isoWeekday();
        let classNameList = [];
        let classNameStr = "";
        let content = "";
        let selectText = "";

        //今天
        if (todayDate === date) {
          classNameList.push(todayClass);
        }
        // //今天以前的日期
        // if (todayDate > date) {
        //   classNameList.push(lastClass);
        // }

        //已预约的日期
        // if (reserveDate === date) {
        //   classNameList.push(reserveClass);
        // }

        //非当前月
        if (currentMonth !== nowMonth) {
          classNameList.push(otherMonthClass);
        }

        // //周末
        // if ([6, 7].includes(currentWeekDay)) {
        //   classNameList.push(dayOffClass);
        // }

        // 已预约的日期
        let obj = {};
        for (let i = 0; i < reverMap.length; i++) {
          const element = reverMap[i];
          let value = element.subscribeDate;
          obj[value] = "已预约";
        }

        if (obj[date]) {
          classNameList.push(holidayClass);
          content = obj[date];
        }

        // 已选择的日期
        let objS = {};
        for (let i = 0; i < reverParam.length; i++) {
          const e = reverParam[i];
          let value = e;
          objS[value] = "已预约";
        }

        if (objS[date]) {
          classNameList.push(selectClass);
          selectText = "已选择";
        }
        //节假日
        // if (holidayMap[date]) {
        //   classNameList.push(holidayClass);
        //   content = holidayMap[date];
        // }

        // //已选中的日期
        // if (reserveDate === date) {
        //   classNameList.push(selectClass);
        // }
        classNameStr = classNameList.join(" ");
        let item = {
          momentObj: currentDate,
          date: date,
          dateDisplay: dateDisplay,
          classNameStr: classNameStr,
          content: content,
          selectText: selectText,
        };
        weekList.push(item);
        currentDate.add(1, "days");
      }
      dates.push(weekList);
    }

    mySelf.setState({
      dates,
    });
    // console.log(dates);
  };

  changeCalendar = () => {
    let mySelf = this;
    let form = mySelf.queryForm.props.form;
    let res = form.getFieldsValue();
    let year = Number(res.year.key);
    let month = Number(res.month.key) - 1;
    let now = moment();
    now.year(year).month(month);

    mySelf.state.monthDisplay = now;
    mySelf.generateDates();
    // console.log(firstDayOfMonthDisplay.format(DATE_FORMAT));
    console.log(now.format(DATE_FORMAT));
  };
  tapDate = (value) => {
    const todayDate = moment().format(DATE_FORMAT);
    if (todayDate > value) {
      message.info("只能设置今天及以后的日期");
      return;
    }
    // 已预约的不能再次选择
    let reserveList = [];
    reverMap.forEach((element) => {
      reserveList.push(element.subscribeDate);
    });
    if (reserveList.includes(value)) {
      message.info("已预约的不能再次选择");
      return;
    }
    // 如果日期已选中,取消选中
    if (reverParam.includes(value)) {
      reverParam.remove(value);
      this.generateDates(value);
    } else {
      reverParam.push(value);
      this.generateDates(value);
    }
  };
  confirmAdd = () => {
    const { dispatch } = this.props;

    let mySelf = this;
    let form = mySelf.queryForm1.props.form;
    let res = form.getFieldsValue();
    form.validateFields((err, fieldsValue) => {
      if (err) return;
      let params = {
        ...fieldsValue,
        data: fieldsValue.data.map((r) => {
          let returnData = {
            subscribeTimeSlot:
              r.subscribeStartTime.format("HH:mm") +
              "-" +
              r.subscribeEndTime.format("HH:mm"),
            subscribeCount: r.subscribeCount,
          };
          // !subscribeType && (returnData.subscribeId = getUuid(32));
          return returnData;
        }),
      };
      if (reverParam.length == 0) {
        message.info("至少选择一天日期!");
        return;
      }
      let reqparams = {
        subscribeDays: reverParam,
        ...params,
      };
      dispatch({
        type: "reservelist1/batchSubscribeDefaultValue",
        payload: reqparams,
        callback: (s, m, data) => {
          if (m == "success") {
            message.info("批量初始化成功");
            this.props.history.push("/reservemanagement/reservelist");
            form.resetFields();
            reverParam = [];
            // this.props.navigation.dispatch(NavigationActions.navigate({ routeName: ‘SearchOrder‘ }))
          }
          cb && cb(s, m, data);
        },
      });
    });
  };

  render() {
    // const {
    //   reserveList1: { data = {} },
    // } = this.props;

    let mySelf = this;
    let { dates } = mySelf.state;

    let renderWeekDays = (days) => {
      let dom = null;
      // console.log(days);
      dom = (
        <React.Fragment>
          {days.map((item, index) => {
            if (item.classNameStr == "today holiday") {
              item.classNameStr = "todayHoliday";
            }
            if (item.classNameStr == "other-month holiday") {
              item.classNameStr = "otherHoliday";
            }
            let styleName = "";
            // console.log(styles[item.classNameStr]);
            let tdDom = (
              <td
                className={styles["unit"]}
                key={index}
                onClick={() => this.tapDate(item.date)}
              >
                {/* <div className={ item.classNameStr + ‘day-cell‘}> */}
                <div
                  className={
                    styles[item.classNameStr]
                      ? styles[item.classNameStr]
                      : styles[
                          item.classNameStr.substring(
                            item.classNameStr.length - 8
                          )
                        ]
                  }
                >
                  <div className="header">
                    {/* {item.date} */}
                    {item.dateDisplay}
                  </div>
                  <div>{item.content}</div>
                  <div>{item.selectText}</div>
                </div>
              </td>
            );
            return tdDom;
          })}
        </React.Fragment>
      );
      return dom;
    };

    let renderWeeks = (dates) => {
      let dom = null;
      // console.log(dates);
      dom = (
        <React.Fragment>
          {dates.map((item, index) => {
            let trDom = <tr key={index}>{renderWeekDays(item)}</tr>;
            return trDom;
          })}
        </React.Fragment>
      );
      return dom;
    };

    return (
      <PageHeaderWrapper title="批量预约设置">
        {/* <Card bordered={false}>
          <div className={styles.tableList}> */}
            {/* <div className={styles.tableListForm}>{this.renderForm()}</div>
            <div className={styles.tableListOperator}>
              <Button
                icon="plus"
                type="primary"
                onClick={() => this.handleModalVisible(true)}
              >
                新建
              </Button>
              <Button
                icon="plus"
                type="primary"
                onClick={() => this.toNewPage(true)}
              >
                批量初始化
              </Button>
            </div> */}
            {/* <StandardTable
            loading={loading}
            data={data}
            columns={this.columns}
            onChange={this.handleStandardTableChange}
          /> */}
          {/* </div>
        </Card> */}
        <div>
          <div className={styles.confirmClass}>
            <Button
              type="primary"
              size={"large"}
              onClick={() => this.confirmAdd()}
            >
              确定添加
            </Button>
          </div>
          <div className={styles.mainSection}>
            <div>
              <QueryFormComponent
                wrappedComponentRef={(inst) => (mySelf.queryForm = inst)}
                // confirmAdd={() => mySelf.confirmAdd()}
                changeCalendar={() => mySelf.changeCalendar()}
              />
              {/* <div className="asda">asdasdasdas</div> */}
              <table border="1" className={styles["le-calendar-container"]}>
                <thead>
                  <tr>
                    <th>一</th>
                    <th>二</th>
                    <th>三</th>
                    <th>四</th>
                    <th>五</th>
                    <th>六</th>
                    <th>日</th>
                  </tr>
                </thead>
                <tbody>{renderWeeks(dates)}</tbody>
                {/* <tfoot>
                <tr>
                  <td>foot1</td>
                  <td>foot2</td>
                </tr>
              </tfoot> */}
              </table>
            </div>
            <QueryFormComponent1
              wrappedComponentRef={(inst) => (mySelf.queryForm1 = inst)}
              // changeCalendar={() => mySelf.changeCalendar()}
              confirmAdd={() => mySelf.confirmAdd()}
            />
            {/* <QueryFormComponent1 /> */}
          </div>
        </div>
      </PageHeaderWrapper>
    );
  }
}

export default LeCalendar;

接口辅助部分

import { store } from ‘@/utils/store‘;
import { getSubscribeTimeSlotList, vehiclePropertiesToSelect, subscribeSetting, subscribeDefaultValue,batchSubscribeDefaultValue,getOrderList } from ‘@/services/api‘;

let currUser = store.getParam(‘currUser‘) || {};

export default {
  namespace: ‘reservelist1‘,

  state: {
    data: {
      list: [],
      pagination: {}
    },
    downloadUrl: null,
    vehiclePropertytypeSelect: []
  },
  effects: {
    *fetch1({ payload, callback }, { call, put }) {
      const response = yield call(getOrderList, {
        ...payload,
        phone: payload.phone || ‘‘,
        startTime: payload.startTime || null,
        endTime: payload.endTime || null,
        orderId: payload.orderId || null,
        plateNumber: payload.plateNumber || null,
        orderState: payload.orderState || null,
        payState: payload.payState || null,
        isSubscribe: payload.isSubscribe || null,
        vdsResult: payload.vdsResult || null,
        parkId: currUser.ParkId || null
      }) || {};
    //   if (callback && typeof callback === ‘function‘) {
       
    // }
      let pageSize = payload.pageSize || 10;
      let current = payload.pageIndex || 1;
      console.log(‘response‘)
      console.log(response)
      callback(response)
      yield put({
        type: ‘save1‘,
        payload: {
          list: response.data ? (response.data.list || []) : [],
          pagination: {
            total: response.data ? (response.data.totalCount || 0) : 0,
            pageSize,
            current
          },
          // downloadUrl: response.data && response.data.totalCount ? getDownloadUrl(‘orderExport‘, {
          //   ...payload,
          //   parkId: parkId
          // }) : null
        }
      })
    },
    *sourceToSelect(_, { call, put }) {
      const vehiclePropertytype = yield call(vehiclePropertiesToSelect);
      yield put({
        type: ‘select‘,
        payload: {
          vehiclePropertytypeList: vehiclePropertytype && Array.isArray(vehiclePropertytype.data) ? vehiclePropertytype.data : []
        }
      })
    },
    *batchSubscribeDefaultValue({ payload, callback }, { call }) {
      const res = yield call(batchSubscribeDefaultValue, {
        ...payload,
        parkId: currUser.ParkId || null,
        operatorId: currUser.OperatorID || null
      });
      callback && callback(res && res.code==‘200‘, res.message);
    },
    // *subscribeSetting({ payload, callback }, { call }) {
    //   const res = yield call(subscribeSetting, {
    //     ...payload,
    //     parkId: currUser.ParkId || null,
    //     operatorId: currUser.OperatorID || null
    //   });
    //   callback && callback(res && res.code==‘200‘, res.message);
    // },
    *subscribeDefaultValue({ payload, callback }, { call }) {
      // let reqUrl = payload.operation ? subscribeSetting : subscribeDefaultValue;
      const res = yield call(subscribeDefaultValue, {
        ...payload,
        parkId: currUser.ParkId || null,
        operatorId: currUser.OperatorID || null
      });
      callback && callback(res && res.code==‘200‘, res.message,res.data);
    }
  },
  reducers: {
    save1(state, { payload }) {
      return {
        ...state,
        data: {
          list: ( payload.list || [] ).map((bean, i) => ({
            ...bean,
            key: i
          })).slice(),
          pagination: payload.pagination
        },
        // downloadUrl: payload.downloadUrl || null
      }
    },
    select(state, { payload }) {
      return {
        ...state,
        vehiclePropertytypeSelect: [
          {
            VehiclePropertyName: ‘‘,
            VehiclePropertyNameLabel: ‘请选择‘,
            VehiclePropertyID: ‘0‘
          },
          ...payload.vehiclePropertytypeList
        ].map(bean => ({
          ...bean,
          VehiclePropertyNameLabel: bean.VehiclePropertyNameLabel || bean.VehiclePropertyName
        }))
      }
    }
  },
}

样式部分

@import ‘~antd/lib/style/themes/default.less‘;
@import ‘~@/utils/utils.less‘;

.tableList {
  .tableListOperator {
    margin-bottom: 16px;
    button {
      margin-right: 8px;
    }
  }
}
.siteCard {
  width: 300px !important;
  border: 1px solid #f0f0f0;
  border-radius: 2px;
}
.tableListForm {
  :global {
    .ant-form-item {
      display: flex;
      margin-right: 0;
      margin-bottom: 24px;
      > .ant-form-item-label {
        width: auto;
        padding-right: 8px;
        line-height: 32px;
      }
      .ant-form-item-control {
        line-height: 32px;
      }
    }
    .ant-form-item-control-wrapper {
      flex: 1;
    }
  }
  .submitButtons {
    display: block;
    margin-bottom: 24px;
    white-space: nowrap;
  }
}

.timeSlotWrap {
  padding: 0 16%;
}

.timeAddButton {
  margin: auto;
  width: 200px;
  display: block;
}

@media screen and (max-width: @screen-lg) {
  .tableListForm :global(.ant-form-item) {
    margin-right: 24px;
  }
}

@media screen and (max-width: @screen-md) {
  .tableListForm :global(.ant-form-item) {
    margin-right: 8px;
  }
}

这样就完成了 效果如下

技术图片

当然,当然还有回显效果,图片没有展示出来。

以上是关于工作中制造的一个react日历轮子的主要内容,如果未能解决你的问题,请参考以下文章

7 个 Python 实战项目代码

造轮子:My97日历控件常用功能记录

Jquery自定义扩展方法--HTML日历控件

造一个Vue(react,angular)和echarts的轮子,从纯技术角度看哪个难度更大?

WPF 自己画日历

使用Swing和Graphics2D在Java中旋转滚轮?