阅读数:

react自定义时间组件

0

说明:react web项目中用到时间选择,我们第一反应都是出于”站在巨人肩膀”的思想,先去找现成的组件。
但往往不符合我们设计狮的设计,没关系,我们要的是思想。
自定义时间组件从头到尾可能用的时间会很多,项目进度没法保证,于是我选择了基于react-mobile-datetimepicker
源码进行改造。改造包括UI,列数可调整,支持时间段选择等

原有项目效果

支持主题更改 ios和andriod可选,年月日十分固定5列不可调整.

datepicker00

原有项目源码结构

datepicker0

改造

目录结构我们不用修改,保持原样就好;

  • 列数可选改造

先分析源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<DatePickerItem
value={value}
min={min}
max={max}
typeName="Year"
format={dateFormat[0]}
onSelect={this.handleDateSelect} />
....
<DatePickerItem
value={value}
min={min}
max={max}
typeName="Month"
format={dateFormat[1]}
onSelect={this.handleDateSelect} />

DatePickerItem是列模版,这里是写死的5列,这样我们就知道了为什么它不支持扩展了,所以我就在这
下手处理就好;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{dateFormat[0] && dateFormat[0] === 'YYYY' && <DatePickerItem
value={value}
min={min}
max={max}
typeName="Year"
format={dateFormat[0]}
onSelect={this.handleDateSelect}/>}
....
{dateFormat[4] && dateFormat[4] === 'mm' && <DatePickerItem
value={value}
min={min}
max={max}
typeName="Minute"
format={dateFormat[4]}
onSelect={this.handleDateSelect}/>}

dateFormat是array类型,类似 dateFormat={[‘YYYY’, ‘M’, ‘D’, ‘hh’, ‘mm’]}
通过控制dateFormat就可以实现列数的控制了;

  • 支持时间显示类型改造

DatePickerItem新增扩展字段fixed,支持数字显示文字后缀,默认为空

1
2
3
4
5
6
7
8
{dateFormat[0] && dateFormat[0] === 'YYYY' && <DatePickerItem
value={value}
min={min}
max={max}
typeName="Year"
fixed={fixed[0]}
format={dateFormat[0]}
onSelect={this.handleDateSelect}/>}

fixed是array类型,类似 fixed={[‘年’, ‘月’, ‘日’, ‘’, ‘’]}
通过控制fixed就可以实现数字显示文字后缀;

  • 支持小时间隔改造

由于两个item的属性完全一样,我们可以基于小时DatePickerItem复制出来一个,通过format来控制
dateFormat={[‘’, ‘’, ‘’, ‘hh’, ‘hh’]},当出现俩hh的时候,组件就可以认为是小时比较,
基于原来的一个value,复制出来一个value2,逻辑基本同value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
constructor(props) {
super(props);
this.state = {
value: nextDate(this.props.value),
value2: this.props.value2 ? nextDate(this.props.value2) : nextDate(this.props.value)
};
}
{dateFormat[3] && dateFormat[3] === 'hh' && <DatePickerItem
value={value}
min={min}
max={max}
typeName="Hour"
fixed={fixed[3]}
format={dateFormat[3]}
onSelect={this.handleDateSelect}/>}
{dateFormat[4] && dateFormat[4] === 'hh' && <DatePickerItem
value={value2}
min={min}
max={max}
typeName="Hour2"
fixed={fixed[3]}
format={dateFormat[3]}
onSelect={this.handleDateSelect2}/>}

当左边时间大于右边时,完成按钮不可点击:

源码:

1
2
3
handleFinishBtnClick() {
this.props.onSelect(this.state.value);
}

改造:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
handleFinishBtnClick() {
if (this._changehandler(this.state.value, this.state.value2)){
this.props.onSelect(this.state.value, this.state.value2);
}
}
_changehandler(left, right) {
let {dateFormat} = this.props;
if (dateFormat[4] && dateFormat[4] === 'hh') {
if (new Date(left).getHours() >= new Date(right).getHours()) {
return false;
}
}
return true;
}

控制按钮样式:

默认绿色,不能点击变灰:

1
2
<a className={this.state.showOk ? "datepicker-navbar-btn color419bf9" : 'datepicker-navbar-btn'}
onClick={this.handleFinishBtnClick}>{ confirmTxt ? confirmTxt : '完成'}</a>

其他细节的代码这里就不啰嗦了,至此整个改造完成,有需要源码一起切磋的可以扫网页下面微我发送,欢迎指点;

调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
handleSelectH(time, time2) {
let tip = new Date(time).getHours() + ':00-' + (new Date(time2).getHours()) + ':00';
this.setState({
timeH1: time,
timeH2: time2,
showDateH: false,
tip: tip
});
}
<DateTimePicker
value={this.state.timeH1}
value2={this.state.timeH2}
isOpen={this.state.showDateH}
theme="ios"
title="请选择时间段"
dateFormat={['', '', '', 'hh', 'hh']}
fixed={['', '', '', ':00', '']}
onSelect={this.handleSelectH}
onCancel={this.handleCancel}/>
  • 样式改造
    将远css文件改造成sass文件,根据UI设计进行对应的改造

效果图

  • 年月日
    datepicker1
    datepicker3

  • 年月日十分
    datepicker4
    datepicker5

  • 时间段:
    datepicker2
    datepicker6


^-^欢迎回复交流^-^


0
赏点咖啡钱^.^