在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)
}
参考文档: