antd v3 select自定义下拉框内容失去焦点时会关闭下拉框

antd 版本 3.19.3 先说一下我遇到的问题,项目中需要做多日期对比,本来想使用 DatePicker 组件,每次选择一个日期,不能一次选择多个,操作起来相对有点麻烦(虽说实现起来很容易),于是,就想结合 SelectCalendar 组件一起使用,想法是很美好的,操作起来就困难重重了,我想要的效果如下图:

采用的是Select 的中 dropdownRender自定义下拉框内容,但是自定义内容中包含Select的话就会因失去焦点而关闭,无法进行二次选择,于是上网查了很多资料,都说如下方法可以解决这个问题,尝试了很多次都无效,不知道是不是我写法不对?时间很紧,不能因为一种方法而卡死,于是就换了一种思路,自己写一个类似Select的组件不就行了,这样就不会又失去焦点的问题了,于是就选择了Dropdown,只要效果一样,谁在乎你怎么实现的。

javascript 复制代码
<Select
  dropdownRender={() => (
    <div
      onMouseDown={(e) => {
        e.preventDefault();
        e.stopPropagation();
      }}
    >
      Some Content
    </div>
  )}
/>

对于 Calendar组件,要使用dateFullCellRender,重新设置单元格,方便添加选中样式,只需要稍微修改一下样式就可以了。

css 复制代码
// CalendarPage.css
.my_calendar .ant-fullcalendar-cell .ant-fullcalendar-selected-day .ant-fullcalendar-value {
  color: #fff !important;
  background: #1677ff !important;
}

.my_calendar .ant-fullcalendar-cell.ant-fullcalendar-selected-day .ant-fullcalendar-value {
  color: unset;
  background: unset;
}

.my_calendar_menu {
  max-height: 300px;
  overflow: auto;
}

Calendar组件二次封装

javascript 复制代码
import React from 'react';
import { Calendar, Card, Row, Col, Menu, Dropdown, Button } from 'antd'
import { DownOutlined } from '@ant-design/icons'
import moment from 'moment'
import './CalendarPage.css'
const dateFormat = 'YYYY-MM-DD'
export default function CalendarPage(props) {
  const { values, handleSelect, ...resProps } = props
  return (
    <Card
      bodyStyle={{ padding: 0, width: 300 }}
      onMouseDown={e => {
        e.preventDefault()
      }}
      style={{ width: 300 }}
    >
      <Calendar
        headerRender={({ value, type, onChange, onTypeChange }) => {
          const start = 0
          const end = 12
          const monthOptions = []
          const current = value.clone()
          const localeData = value.localeData()
          const months = []
          for (let i = 0; i < 12; i++) {
            current.month(i)
            months.push(localeData.monthsShort(current))
          }
          for (let index = start; index < end; index++) {
            monthOptions.push(
              <Menu.Item className="month-item" key={`${index}`}>
                {months[index]}
              </Menu.Item>
            )
          }
          const month = value.month()
          const year = value.year()
          const options = []
          for (let i = year - 10; i < year + 10; i += 1) {
            options.push(
              <Menu.Item key={i} value={i} className="year-item">
                {i}
              </Menu.Item>
            )
          }
          const menu = (
            <Menu
              size="small"
              onClick={newYear => {
                const now = value.clone().year(newYear.key)
                onChange(now)
              }}
              className="my_calendar_menu"
            >
            	{options}
            </Menu>
          )
          const menu2 = (
            <Menu
              size="small"
              onClick={selectedMonth => {
                const newValue = value.clone()
                newValue.month(parseInt(selectedMonth.key, 10))
                onChange(newValue)
              }}
              className="my_calendar_menu"
            >
            	{monthOptions}
            </Menu>
          )
          return (
            <div style={{ padding: 10 }}>
              <Row type="flex" justify="end">
                <Col>
                  <Dropdown size="small" overlay={menu}>
                    <Button>
                      {String(year)}
                      <DownOutlined />
                    </Button>
                  </Dropdown>
                </Col>
                <Col>
                  <Dropdown size="small" overlay={menu2}>
                    <Button style={{ marginLeft: 10 }}>
                      {months[month]}
                      <DownOutlined />
                    </Button>
                  </Dropdown>
                </Col>
              </Row>
            </div>
          )
        }}
        fullscreen={false}
        className="calendar"
        dateFullCellRender={date => {
          let de = moment(date).format(dateFormat)
          let cls = ''
          if (values && values.indexOf(de) !== -1) {
            cls = 'ant-fullcalendar-selected-day'
          } else {
            cls = ''
          }
          return (
            <div
              className={cls}
              onClick={() => {
                handleSelect && handleSelect(moment(date).format(dateFormat))
              }}
            >
              <div className="ant-fullcalendar-value" style={{ textAlign: 'center' }}>
                {moment(date).date()}
              </div>
            </div>
          )
        }}
        {...resProps}
      />
    </Card>
  )
}

使用

javascript 复制代码
// 引入 CalendarPage 组件
import CalendarPage from './CalendarPage'
<Select
  dropdownRender={() => (
      <CalendarPage
      	handleSelect={e=>{
      		// 逻辑处理,动态设置values
      	}
      	values={['2023-06-01', '2023-06-25']}
      />
  )}
/>
相关推荐
神雕杨1 小时前
node js 过滤空白行
开发语言·前端·javascript
网络安全-杰克1 小时前
《网络对抗》—— Web基础
前端·网络
m0_748250741 小时前
2020数字中国创新大赛-虎符网络安全赛道丨Web Writeup
前端·安全·web安全
周伯通*1 小时前
策略模式以及优化
java·前端·策略模式
艾斯特_1 小时前
前端代码装饰器的介绍及应用
前端·javascript
Sokachlh1 小时前
【elementplus】中文模式
前端·javascript
轻口味1 小时前
【每日学点鸿蒙知识】hap安装报错、APP转移账号、import本地文件、远程包构建问题、访问前端页面方法
前端·华为·harmonyos
m0_748245341 小时前
BY组态-低代码web可视化组件
前端·低代码
web182854825122 小时前
ctfshow-web 151-170-文件上传
前端·状态模式
轻口味2 小时前
【每日学点鸿蒙知识】Web请求支持Http、PDF展示、APP上架应用搜索问题、APP备案不通过问题、滚动列表问题
前端·http·harmonyos