当初仍是antd2.X
版本时,DatePicker
组件还不支持mode
属性,不能单独设置为年份选择器。可是公司项目恰好不少地方都有根据年份作筛选的需求,由于antd
不支持,所以,使用了Select
组件来实现年份选择。html
可是,遭到了客户的强烈吐槽,“大家这个UI风格仍是要一致撒”,哈哈😄,官方吐槽最为致命!没办法了,我本身也无法说服本身了,只能照着antd
的UI风格本身撸一个YearPicker
咯。(时间选择控件YearPicker
基于React
,antd
www.cnblogs.com/zyl-Tara/p/…)可是,老实说,效果不怎么理想,只能说实现了UI风格的一致,以及值的选择。可是,组件值的清除、动画过渡效果等都没有深刻处理。react
庆幸的是,很快antd3.X
终于支持了年份选择。设置mode="year"
即可以使用年份选择器。真是普天同庆!😎git
话很少说,赶忙用起来!上代码,github
import React, { Component } from 'react'; import { DatePicker } from 'antd'; export default class extends Component { onChange = val => { console.log(val) } render() { return ( <div> <DatePicker placeholder="请选择年份" mode="year" onChange={this.onChange} /> </div> ); } }复制代码
界面呈现出只有年份的选择器,nice!bash
可是,接下来,你就直接懵了。由于无论你怎么点击按钮选择年份都不会起做用,onChange
事件根本不会触发,因此value
获取不了!markdown
百思不得其解,而后去翻看ant design
的github
issue
。终于看到一条中肯的comment
。
antd
<DatePicker mode="year" onPanelChange={(v) => {console.log(v)}}/>复制代码
只须要把onChange
换成onPanelChange
就行了。因而能够获取时间了。测试
然而,另外一个问题出现了,时间虽然是获取了,可是面板并无关闭。动画
继续查找问题,发现当DatePicker
变为受控后,须要open
这个属性控制面板的关闭。
import React, { Component } from 'react'; import { DatePicker } from 'antd'; export default class extends Component { state = { isopen: false, time: null } render() { const { isopen, time } = this.state return ( <div> <DatePicker value={time} open={isopen} mode="year" placeholder="请选择年份" format="YYYY" onFocus={() => {this.setState({isopen: true})}} onBlur={() => {this.setState({isopen: false})}} onPanelChange={(v) => { console.log(v) this.setState({ time: v, isopen: false }) }}/> </div> ); } }复制代码
同时,经过onFocus
和onBlur
控制获取焦点和失焦时面板的显隐。
一切彷佛很完美,可以获取值,也能正常关闭面板。
然而,快乐的时光老是短暂的,很快,测试便提出缺陷,“这个年份选择器为何选择完年份后会有闪开闪关的效果,不符合要求哈”
“😂,哦,那我再看看呢”
还真的是会闪,明明记得以前没有这个问题啊,算了继续看看问题在哪儿吧。
查看文档,发现DatePicker
有个onOpenChange
方法,是这样描述的:弹出日历和关闭日历的回调,function(status)
因此,能够经过onOpenChange
方法判断当前的操做是要面板关闭仍是打开,来控制面板的显隐。
因此,综上全部的思考,解决思路以下:
一、onChange
方法没法触发获取到值,须要换成onPanelChange
二、面板的显示隐藏须要open
属性进行手动控制
三、onFocus
、onBlur
会致使闪开闪关,须要换成onOpenChange
import React, { Component } from 'react'; import { DatePicker } from 'antd'; export default class extends Component { state = { isopen: false, time: null } render() { const { isopen, time } = this.state return ( <div> <DatePicker value={time} open={isopen} mode="year" placeholder="请选择年份" format="YYYY" onOpenChange={(status) => { if(status){ this.setState({isopen: true}) } else { this.setState({isopen: false}) } }} onPanelChange={(v) => { console.log(v) this.setState({ time: v, isopen: false }) }} /> onChange={() => { this.setState({time: null}) }} </div> ); } }复制代码
如今能够正常获取值,而且开关面板流畅,不会出现闪开闪关的效果。固然,细心的你可能发现我在组件中用到了onChange
事件,而且作了对值置空的操做。
注意:这里的time
置空必定要设置为null
。由于组件接受的是一个对象。
这是为何呢?
咱们都知道DatePicker
组件有一个allowClear
属性,让咱们能够经过点击输入框中的❌icon来清除选择的值。
可是当咱们设置mode=“year”
后,这个allowClear
便不起做用了。怎么办呢?
由于onChange
事件不会在选择值的时候触发,可是点击清除icon 却会触发。所以经过onChange
事件即可以达到清除value
的效果。
ok,完美解决~ 🎉