基于Taro-UI封装的时间选择器

在taro-ui的组件库中,选择器picker是分开了的,mode=date的日期选择器和mode=time的时间选择器,如下:

mode=time:

mode=date:

现在项目需求是实现年月日和小时的选择,对此,在网上查找了很多关于此的组件封装,最后根据一份代码进行修改,得到了如下效果:

组件结构目录:

// index.js

import React, {Component} from 'react';
import { AtIcon } from 'taro-ui';
import { View, Text, PickerView, PickerViewColumn, } from '@tarojs/components';
import { getPickerViewList, getDate, getArrWithTime, formatDate, getDayList } from './utils';
import './index.less'


export default class DateTimePicker extends Component {
  static externalClasses = ['wrap-class', 'select-item-class'];

  // DateTimePicker.prototype = {
//     initValue: PropTypes.string, //初始化时间
//     onClear: PropTypes.func, //清除选择的时间触发
//     onCancel: PropTypes.func, //时间picker 取消时触发
//     onOk: PropTypes.func, //时间picker 确定时触发
// };

  state = {
    yearList: [],   //年 -下拉
    monthLsit: [], //月 -下拉
    dayList: [], //日 -下拉
    hourList: [], //时 -下拉
    selectIndexList: [1, 1, 1, 1, 1], //PickerViewColumn选择的索引
    fmtInitValue: "", //初始值
    current: '', //当前选择的数据
    visible: false, //是否可见
    hasChange: false, //是否更改
    year: '',  //时间值
    month: '',
    day: '',
    hour: '',

  };
  // 打开时间选择的模态框 - 根据当前时间初始化picker-view的数据
  openModal = () => {
    const {placeholder}=this.props
    console.log(placeholder)
    const { current, fmtInitValue } = this.state;
    const selectIndexList = [];
    const arr = getArrWithTime(placeholder); //优先当前选择的值,其次默认值,其次当前值
    const { yearList, monthLsit, dayList, hourList } = getPickerViewList();
    const [year, month, day, hour] = arr;

    //根据arr  数据索引
    selectIndexList[0] = yearList.indexOf(arr[0] + '年');
    selectIndexList[1] = monthLsit.indexOf(arr[1] + '月');
    selectIndexList[2] = dayList.indexOf(arr[2] + '日');
    selectIndexList[3] = hourList.indexOf(arr[3] + '点');

    this.setState({
      selectIndexList,
      visible: true,
      yearList,
      monthLsit,
      dayList,
      hourList,
      year,
      month,
      day,
      hour,
    });
  };
  // 取消
  cancelHandel = () => {
    this.setState({
      visible: false,
      hasChange: false,
    });

    const { year, month, day, hour} = this.state;
    const current = formatDate(year, month, day, hour);

    this.props.onCancel && this.props.onCancel({ current });
  };
  // 确定
  okHandel = () => {
    const { placeholder } = this.props;
    const { year, month, day, hour, hasChange  } = this.state;
    const current = formatDate(year, month, day, hour);

    this.setState({
      visible: false,
    });

    if (hasChange) {
      this.setState({
        current,
      });
      this.props.onOk && this.props.onOk({ current });
    }
    else{
      this.setState({
        current:placeholder,
      });
      this.props.onOk && this.props.onOk({ current });
    }
  };
  // 切换
  changeHandel = (e) => {
    const selectIndexList = e.detail.value;
    const [yearIndex, monthIndex, dayIndex, hourIndex] = selectIndexList;
    const { yearList, monthLsit, dayList, hourList } = this.state;
    const yearStr = yearList[yearIndex];
    const monthStr = monthLsit[monthIndex];
    const dayStr = dayList[dayIndex];
    const hourStr = hourList[hourIndex];
    const year = Number(yearStr.substr(0, yearStr.length - 1));
    const month = Number(monthStr.substr(0, monthStr.length - 1));
    const day = Number(dayStr.substr(0, dayStr.length - 1));
    const hour = Number(hourStr.substr(0, hourStr.length - 1));

    const newDayList = getDayList(year, month);

    this.setState({
      selectIndexList,
      visible: true,
      dayList:newDayList,
      hourList,
      year,
      month,
      day,
      hour,
      hasChange: true,
    });
  };
  // 清除数据
  clear = () => {
    this.setState({
      current: ''
    });
    this.props.onClear && this.props.onClear({ current: '' });
  };

  componentDidMount() {
    const { initValue } = this.props;
    const fmtInitValue = getDate(initValue);
    this.setState({ fmtInitValue });
  }

  render() {
    const { visible, current, yearList, monthLsit, dayList, hourList, selectIndexList } = this.state;
    const { placeholder ,disabled } = this.props;
    if (disabled) {
      return (
        <View className="datetime-picker-wrap wrap-class">
          <View className="selector-wrap">
            <View className={`select-item select-item-class ${disabled ? 'disabled' : ''}`}>
              {placeholder}
            </View>
          </View>
        </View>
      );
    }

    return (
      <View className="datetime-picker-wrap wrap-class">
        <View className="selector-wrap">
          <View className="select-item select-item-class" onClick={this.openModal}>
            {placeholder}
          </View>
        </View>
        {visible
          && <View className="wrapper">
            {/*日期模态框 */}
            <View className="model-box-bg"/>
            <View className="model-box">
              <View className="model-picker">
                <View className="button-model">
                  <Text class="btn-txt" onClick={this.cancelHandel}>取消</Text>
                  <Text class="btn-txt" onClick={this.okHandel}>确定</Text>
                </View>
                <View className="cont_model">
                  <PickerView className="pick-view" style={{textAlign:'right'}} value={selectIndexList} onChange={this.changeHandel}>
                    {/*年*/}
                    <PickerViewColumn className="picker-view-column">
                      {
                        yearList.length && yearList.map((item, index) =>
                          <View key={String(index)} className="pick-view-column-item">{item}</View>)
                      }
                    </PickerViewColumn>
                    {/*月*/}
                    <PickerViewColumn className="picker-view-column">
                      {
                        monthLsit.length && monthLsit.map((item, index) =>
                          <View key={String(index)} className="pick-view-column-item">{item}</View>)
                      }
                    </PickerViewColumn>
                    {/*日*/}
                    <PickerViewColumn className="picker-view-column">
                      {
                        dayList.length && dayList.map((item, index) =>
                          <View key={String(index)} className="pick-view-column-item">{item}</View>)
                      }
                    </PickerViewColumn>
                    {/*时*/}
                    <PickerViewColumn className="picker-view-column">
                      {
                        hourList.length && hourList.map((item, index) =>
                          <View key={String(index)} className="pick-view-column-item">{item}</View>)
                      }
                    </PickerViewColumn>
                  </PickerView>
                </View>
              </View>
            </View>
          </View>}
      </View>
    );
  }
}

// index.less

.datetime-picker-wrap {
  .selector-wrap {
    display: flex;
    align-items: center;
    background: #FFFFFF;
    //padding: 0 20px;
    .select-item {
      flex: 1;
      font-size: 32rpx;
      text-align: right;
    }
  }
  .wrapper {
    .model-box-bg {
      position: absolute;
      top: 0;
      left: 0;
      z-index: 10000;
      width: 100%;
      height: 100%;
      background: #000;
      opacity: 0.3;
    }
    .model-box {
      position: absolute;
      bottom: 0;
      left: 0;
      z-index: 999999;
      width: 100%;
      background: #fff;
    }

    .model-picker {
      position: relative;
      .button-model {
        height: 80px;
        width: 100%;
        background: #fff;
        position: relative;
        border-bottom: 1px solid #d9d9d9;
        .btn-txt {
          color: #007aff;
          position: absolute;
          background: transparent;
          border: none;
          line-height: 80px;
          &:first-child {
            left: 32px;
          }
          &:last-child {
            right: 32px;
          }
        }
      }
      .pick-view {
        width: 100%;
        height: 600px;
        .picker-view-column {
          text-align: center;
          .pick-view-column-item {
            line-height: 50PX;
          }
        }
      }

    }
  }
}
// utils.js

function addZero(num) {
  return Number(num) < 10 ? `0${num}` : num;
}

export const formatDate = (year, month, day, hour) => {
  const newmonth = addZero(month);
  const newday = addZero(day);
  const newhour = addZero(hour);

  return year + '-' + newmonth + '-' + newday + ' ' + newhour + ':00:00';
};

// 获取当前时间
export const getDate = (value) => {
  let date = '';
  if (value) {
    date = new Date(value);
  } else {
    date = new Date();
  }
  const y = date.getFullYear(),
    m = date.getMonth() + 1,
    d = date.getDate(),
    h = date.getHours(); //获取当前小时数(0-23)
  return formatDate(y, m, d, h);
};

// 获取对应年份月份的天数
export const getMonthDay = (year, month) => {
  var d = new Date(year, month, 0);
  return d.getDate();
};


// 根据时间2019-01-02 09点 得到 ['2019','1','2','9']
export const getArrWithTime = (str) => {
  let arr1 = str.split(' ');
  let arr2 = (arr1[0]).split('-');
  let arr3 = arr1[1].split(':00:00');
  let arr = arr2.concat(arr3[0]);

  arr[1] = arr[1].startsWith('0') ? arr[1].substr(1, arr[1].length) : arr[1];
  arr[2] = arr[2].startsWith('0') ? arr[2].substr(1, arr[2].length) : arr[2];
  arr[3] = arr[3].startsWith('0') ? arr[3].substr(1, arr[3].length) : arr[3];

  return arr;
};


// 获取月份天数
export const getDayList = (year, month) => {
  const dayList = [];
  var d = new Date(year, month, 0);
  for (let i = 1; i <= d.getDate(); i++) {
    dayList.push(i + "日");
  }

  return dayList;
};

// 获取最近的年、月、日、时、分的集合
export const getPickerViewList = () => {
  const now = new Date();
  const year = now.getFullYear();
  const month = now.getMonth() + 1;
  const yearList = [];
  const monthLsit = [];
  const dayList = getDayList(year, month);
  const hourList = [];

  for (let i = 1970; i <= 2070; i++) {
    yearList.push(i + "年");
  }
  for (let i = 1; i <= 12; i++) {
    monthLsit.push(i + "月");
  }

  for (let i = 0; i <= 23; i++) {
    hourList.push(i + "点");
  }

  return { yearList, monthLsit, dayList, hourList};
};

组件调用:

<View className='GetInfo'>
  <View className='GetInfoText'>陪护开始日期</View>
     <View className='GetInfoInput'>
        <DateTimePicker onOk={(value) => this.onStartDateChange( value)} placeholder={startTime} disabled={editMode} />
     </View>
</View>

 点击确认调用的函数返回的结果current即为选择的时间:

  onStartDateChange = ({ current }) => {
    console.log(current)
  }

参考文档:

taro-ui官网

基于Taro封装的日期时间DateTimePicker组件

  • 11
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值