當初仍是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
獲取不了!antd
百思不得其解,而後去翻看ant design
的github
issue
。終於看到一條中肯的comment
。
測試
<DatePicker mode="year" onPanelChange={(v) => {console.log(v)}}/>複製代碼
只須要把onChange
換成onPanelChange
就行了。因而能夠獲取時間了。ui
然而,另外一個問題出現了,時間雖然是獲取了,可是面板並無關閉。this
繼續查找問題,發現當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,完美解決~ 🎉