一、描述

本来计划 rax-datepicker 和 rax-timepicker 一起写的,后面发现,源码结构都一样,差的不多就把后者一笔带过了。

rax-datepicker 是 rax 的内置组件,用来实现日期的选择,官方文档地址:

按照文档的说明,rax-datepicker 调用的是系统原生的日期选择,而由于 picker 组件在 H5 降级时候本身存在的问题(这个问题是由 weex-picker 引起的,具体请移步:http://www.ptbird.cn/weex-picker-web-ios-anfroid-platform.html

而 rax 在实现的时候,直接避开了这个坑,没有解决,而是选择绕开。

二、组件源码

组件源码还是相对简单的,因为其本质上还是依赖了 weex 的 module picker,本身只是上层做了一次封装而已,没有从底部实现,因为 weex 已经实现了。

同样的,对于 weex 环境和 web 容器环境,为了避开前面提到的坑,使用了两种不同的渲染方式。

1、web 容器环境

我很不可思议的是,web 环境下,直接渲染了原生的 input 组件,<input type="date">

return (
  <input
    type={'date'}
    value={selectedValue}
    defaultValue={selectedValue}
    min={minimumDate}
    max={maximumDate}
    onChange={(e) => {
      onDateChange && onDateChange(e.target.value);
    }}
    style={style} />
);

这可以说是一种这种行为,因为在目前的手机浏览器中,基本上实现了 input[type=date],能够在手机上唤起日期选择,可以说是系统的一种实现方式,浏览器接入了,所以各个浏览器样式差不多,当然,这是在 iphone 上的结果,没有看在 android 的表现是否也是如此。

虽然只是渲染了一个 input,但确实可以实现日期选择,各个浏览器的 H5 环境效果,将在后面单独列出来。

2、weex 容器环境

weex 容器环境中,实现方式和 rax-picker 差不多,也是通过一个 rax-touchable 组件触发 press 事件,然后再主动的触发 @weex-module/picker

因此 handlePress 方法十分关键,同样需要注意的是,因为 web 容器使用了系统默认的 input[type=date] 表单,所以不需要触发 press,而是直接将事件赋上去。

在 weex 容器时,将需要的 prop 传递给 picker 模块即可,并且通过 picker 的模块事件触发 onDateChange

  handlePress = () => {
    if (isWeex) {
      const {
        onDateChange,
        selectedValue,
        minimumDate,
        maximumDate,
      } = this.props;
      const picker = __weex_require__('@weex-module/picker');

      picker.pickDate({
        value: selectedValue,
        max: maximumDate,
        min: minimumDate,
      }, event => {
        if (event.result === 'success') {
          onDateChange && onDateChange(event.data);
        }
      });
    }
  }

所以在渲染的过程中,直接将 selectedValue 放在 <Touchable> -> <Text> 中用来显示当期选择的值:

if (isWeex) {
  return (
    <TouchableHighlight {...this.props} onPress={this.handlePress} style={touchableStyle}>
      <Text style={textStyle}>
        {selectedValue}
      </Text>
    </TouchableHighlight>
  );
}

三、使用

1、实践代码

import {createElement, Component} from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import DatePicker from 'rax-datepicker';
import styles from './App.css';

class App extends Component {
  state = {
    date:'2000-01-01'
  }
  changeHandle = (date) => {
    this.setState({
      date
    });
  }
  render() {
    return (
      <View style={styles.app}>
        <Text>选择日期:{this.state.date}</Text>
        <DatePicker 
        style={styles.picker}
          selectedValue={this.state.date}
          minimumDate={'2000-01-01'}
          maximumDate={'2029-01-01'}
          onDateChange={this.changeHandle}
        >
        </DatePicker>
      </View>
    );
  }
}

export default App;

使用的样式:

.app {
  flex: 1;
  justify-content: center;
  align-items: center;
}

.picker{
  color:red;
  font-size:30;
  border-width:1px;
  border-color:#cccccc;
  border-radius:20;
  padding:40;
}

2、效果

1)weex 容器

1.jpg

2)safari

2.jpg

3) iphone chrome

3.jpg

4)iphone 微信内置浏览器

4.jpg

5)PC chrome 浏览器

33.jpg

四、TimePicker 组件

类似 rax-datepickerrax-timepicker 的源代码几乎差不多,也是一样的讨论,在 weex 容器下,还是基于 weex.picker 进行渲染,而在 web 环境下,直接渲染 input[type=time]