关于antd 日期组件只选择年份,设置mode=year无法获取value的解决办法

antd3.0后的某个版本后终于支持了只选择年份的设置。当时2.x版本的时候还不支持只选择年份,我们项目中有这个只选择年份的需求,为了ui风格的一致,只好自己撸了一个。

如今真是普天同庆!😄😄

然而,事情并没有这么简单。

import React, { Component } from 'react';
import { DatePicker } from 'antd';

export default class extends Component {
  onChange = val => {
    console.log(val)
  } 
  
  render() {
    return (
        <div>
            <DatePicker mode="year" onChange={this.onChange}/>
        </div>
    );
  }  
}

当你按照这段代码,打开界面你发现,nice!真的出现了只有年份的界面!❤️❤️

然后,下一秒你就该吐血了。因为你发现你点击选择任何一个按钮都不会有反应,onChange事件不会触发!你根本拿不到时间对象!

气不气?👹👹

百思不得其解,然后去翻看ant design的github issue。终于看到一条中肯的comment。

https://github.com/ant-design/ant-design/issues/10242#issuecomment-393055938

<DatePicker mode="year" onPanelChange={(v) => {console.log(v)}}/>

只需要把onChange换成onPanelChange就好了。大功告成!你可以愉快的获取时间了。

然而,你还发现一个问题,时间虽然是获取了,但是面板并没有关闭。😠😠

继续查找问题,发现需要open这个属性控制面板的关闭,这个大概是antd团队没考虑到?🤔️🤔️

解决办法如下:

import React, { Component } from 'react';
import { DatePicker } from 'antd';

export default class extends Component {
  state =  {
    isopen: false,
    time: null
  }
  
  render() {
    return (
        <div>
            <DatePicker value={this.state.time} open={this.state.isopen} mode="year" format="YYYY" onFocus={() => {this.setState({isopen: true})}} 
            onBlur={() => {this.setState({isopen: false})}} 
            onPanelChange={(v) => {
              console.log(v)
              this.setState({
                time: v,
                isopen: false
              })
              }}/>
        </div>
    );
  }  
}        

添加了open的控制才真的搞定了!🎉🎉🎉

2019-05-31追加内容>>>>>>

然而,快乐的时光总是短暂,很快,测试便提出问题。”好像你这个点击选择年份后面板会闪开闪关哦,不符合要求哈“

“😂,哦,那我再看看呢”

还真的有这个问题,但是我记得之前不会闪啊。

算了,继续查找问题,发现一个方法onOpenChange,文档描述:弹出日历和关闭日历的回调,function(status){}

于是通过这个方法,判断当前的操作是要面板打开还是关闭,然后来控制面板的显示关闭。

import React, { Component } from 'react';
import { DatePicker } from 'antd';

export default class extends Component {
  state =  {
    isopen: false,
    time: null
  }

  handlePanelChange = (value) => {    
    console.log(">>>>>", value)    
    this.setState({      
      time: value,      
      isopen: false    
    })  
  } 
 
  handleOpenChange = (status) => {    
    // console.log(status)    
    if(status){      
        this.setState({isopen: true})    
    } else {      
        this.setState({isopen: false})    
    }  
  }  

  clearValue = () => {    
    this.setState({      
        time: null    
    })  
  }
  
  render() {
    return (
        <div>
            <DatePicker               
                value={this.state.time}               
                open={this.state.isopen}               
                mode="year"               
                placeholder='请选择年份'              
                format="YYYY"              
                onOpenChange={this.handleOpenChange}              
                onPanelChange={this.handlePanelChange}              
                onChange={this.clearValue}            
            />        
        </div>
    );
  }  
}

从代码可以看到,handleOpenChange便可以控制面板的开关,并且不会闪了。

细心的你可能还发现我在onChange的时候绑定了一个clearValue函数。诶?这是为什么呢?

我们都知道,DatePicker有个属性是allowClear,默认为true。表示,可以通过输入框中的❎图标清除输入框中的值。

但是,现在点击这个清除icon却没有任何反应,值并不会被清除掉。

难不难受?😂

然后,我突然想到,这个清除会不会触发onChange事件呢?

很明显,选择值的时候不会触发onChange事件,但是点击清除icon时触发了!

于是通过onChange事件我可以愉快的清除值了~~

完美解决问题 😝

posted @ 2018-12-29 17:28  一江西流  阅读(18458)  评论(10编辑  收藏  举报