Ant Design中DatePicker設置mode="year"沒法獲取value及關閉面板的解決方案

一、前情提要

當初仍是antd2.X版本時,DatePicker組件還不支持mode屬性,不能單獨設置爲年份選擇器。可是公司項目恰好不少地方都有根據年份作篩選的需求,由於antd不支持,所以,使用了Select組件來實現年份選擇。html

可是,遭到了客戶的強烈吐槽,「大家這個UI風格仍是要一致撒」,哈哈😄,官方吐槽最爲致命!沒辦法了,我本身也無法說服本身了,只能照着antd的UI風格本身擼一個YearPicker咯。(時間選擇控件YearPicker基於Reactantd 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 designgithub issue。終於看到一條中肯的comment
測試

github.com/ant-design/…
動畫

<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>
    );
  }  
}複製代碼

同時,經過onFocusonBlur控制獲取焦點和失焦時面板的顯隱。

一切彷佛很完美,可以獲取值,也能正常關閉面板。

然而,快樂的時光老是短暫的,很快,測試便提出缺陷,「這個年份選擇器爲何選擇完年份後會有閃開閃關的效果,不符合要求哈」

「😂,哦,那我再看看呢」

還真的是會閃,明明記得以前沒有這個問題啊,算了繼續看看問題在哪兒吧。

三、解決方案

查看文檔,發現DatePicker有個onOpenChange方法,是這樣描述的:彈出日曆和關閉日曆的回調,function(status)

因此,能夠經過onOpenChange方法判斷當前的操做是要面板關閉仍是打開,來控制面板的顯隱。

因此,綜上全部的思考,解決思路以下:

一、onChange方法沒法觸發獲取到值,須要換成onPanelChange

二、面板的顯示隱藏須要open屬性進行手動控制

三、onFocusonBlur會致使閃開閃關,須要換成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,完美解決~ 🎉

相關文章
相關標籤/搜索