uniapp使用picker-view+u-popup实现年月日时分秒时间选择器,可以自定义弹窗、选择器的样式,亲测,非常好用!

1,471 阅读1分钟

原创链接(使用的picker多列选择器,如不需要更改弹窗样式的可移步参考原创使用picker实现):blog.csdn.net/Arbort_/art…

先看效果图

image.png

废话不多说,直接上代码,可直接复制粘贴使用

  1. 创建 dateTimePicker.js 文件,做主要的逻辑操作
/**
 * 自定义多列时间选择器
 */
function withData(param) {
  return param < 10 ? '0' + param : '' + param;
}

function getLoopArray(start, end) {
  var start = start || 0;
  var end = end || 1;
  var array = [];
  for (var i = start; i <= end; i++) {
    array.push(withData(i));
  }
  return array;
}

function getMonthDay(year, month) {
  var flag = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0),
    array = null;

  switch (month) {
    case '01':
    case '03':
    case '05':
    case '07':
    case '08':
    case '10':
    case '12':
      array = getLoopArray(1, 31)
      break;
    case '04':
    case '06':
    case '09':
    case '11':
      array = getLoopArray(1, 30)
      break;
    case '02':
      array = flag ? getLoopArray(1, 29) : getLoopArray(1, 28)
      break;
    default:
      array = '月份格式不正确,请重新输入!'
  }
  return array;
}

function getNewDateArry() {
  // 当前时间的处理
  var newDate = new Date();
  var year = withData(newDate.getFullYear()),
    mont = withData(newDate.getMonth() + 1),
    date = withData(newDate.getDate()),
    hour = withData(newDate.getHours()),
    minu = withData(newDate.getMinutes()),
    seco = withData(newDate.getSeconds());

  return [year, mont, date, hour, minu, seco];
}

function dateTimePicker(startYear, endYear, date) {
  // 返回默认显示的数组和联动数组的声明
  var dateTime = [],
    dateTimeArray = [
      [],
      [],
      [],
      [],
      [],
      []
    ];
  var start = startYear || 2000;
  var end = endYear || 2100;
  // 默认开始显示数据
  var defaultDate = date ? [...date.split(' ')[0].split('-'), ...date.split(' ')[1].split(':')] : getNewDateArry();
  // 处理联动列表数据
  /*年月日 时分秒*/
  dateTimeArray[0] = getLoopArray(start, end);
  dateTimeArray[1] = getLoopArray(1, 12);
  dateTimeArray[2] = getMonthDay(defaultDate[0], defaultDate[1]);
  dateTimeArray[3] = getLoopArray(0, 23);
  dateTimeArray[4] = getLoopArray(0, 59);
  dateTimeArray[5] = getLoopArray(0, 59);

  dateTimeArray.forEach((current, index) => {
    dateTime.push(current.indexOf(defaultDate[index]));
  });

  return {
    dateTimeArray: dateTimeArray,
    dateTime: dateTime
  }
}
/**格式化日期 */
function generateTimeStr(dateTimeArray, dateTime) {
  const timeStr =
    dateTimeArray[0][dateTime[0]] +
    "-" +
    dateTimeArray[1][dateTime[1]] +
    "-" +
    dateTimeArray[2][dateTime[2]] +
    " " +
    dateTimeArray[3][dateTime[3]] +
    ":" +
    dateTimeArray[4][dateTime[4]] +
    ":" +
    dateTimeArray[5][dateTime[5]];
  return timeStr;
}
module.exports = {
  dateTimePicker,
  getMonthDay,
  generateTimeStr
};
  1. 在组件中使用picker-view,在这里我需要实现一个从下往上弹出的弹窗,弹窗里面包含了时间选择器,所以我使用的是uView组件库的u-popup,大家可以根据自己项目所需进行更改
<template>
  <view>
    <view @click="showPopup = true">我选择的时间:{{ time }}</view>

    <u-popup :show="showPopup" mode="bottom" @close="showPopup = false">
          <view class="popup_container">
            <view class="popup_title">弹窗标题</view>
            <view class="popup_picker">
              <picker-view indicator-style="height:45px; background-color:#f7f7f7; z-index: 0;" :value="defaultDate"
                @change="pickDate" class="picker_view" :immediate-change="true">
                <picker-view-column>
                  <view class="picker_item" v-for="(item,index) in dateTimeArray[0]" :key="index">{{item}}年</view>
                </picker-view-column>
                <picker-view-column>
                  <view class="picker_item" v-for="(item,index) in dateTimeArray[1]" :key="index">{{item}}月
                  </view>
                </picker-view-column>
                <picker-view-column>
                  <view class="picker_item" v-for="(item,index) in dateTimeArray[2]" :key="index">{{item}}日</view>
                </picker-view-column>
                <picker-view-column>
                  <view class="picker_item" v-for="(item,index) in dateTimeArray[3]" :key="index">{{item}}时</view>
                </picker-view-column>
                <picker-view-column>
                  <view class="picker_item" v-for="(item,index) in dateTimeArray[4]" :key="index">{{item}}分</view>
                </picker-view-column>
                <picker-view-column>
                  <view class="picker_item" v-for="(item,index) in dateTimeArray[5]" :key="index">{{item}}秒</view>
                </picker-view-column>
              </picker-view>
            </view>
            <view class="popup_btn">
              <view class="btn cancel_btn" @click="showPopup = false">取消</view>
              <view class="btn confirm_btn" @click="confirmDate">确认</view>
            </view>
          </view>
        </u-popup>
   </view>
 </template>
  1. JS逻辑操作部分,需要做的是获取到当前的年月日时分秒,并且在切换月份时,改变日期(因为每个月份的日期是不一样的)
<script>
// 从你放JS文件的位置导入进来,我是放在lib文件夹里面的
 import {
   dateTimePicker,
   getMonthDay,
   generateTimeStr
 } from '../../../lib/dateTimePicker.js'
 
 export default {
   data() {
      // 获取当前日期
     let date = new Date();
     // 我这里需要的是2023-2050年的日期
     // 获取完整的年月日时分秒以及默认显示的数组, dateTimePicker(起始年份, 截止年份);
     let obj = dateTimePicker(date.getFullYear(), 2050);
     return {
       time: '',
       showPopup: false, // 弹窗的显示与隐藏
       defaultDate: obj.dateTime, // 时间默认值 是一个数组,数组里面是下标
       dateTimeArray: obj.dateTimeArray,  // 时间默认数据 是一个数组,里面是所有的年月日时分秒
     };
   },
   onLoad() {},
   methods: {
       // 滑动时间选择器时触发change事件
     pickDate(e) {
       console.log('时间选择器在滑动')
       let val = e.detail.value
       // 当当前选择的月份与默认的月份不同时,改变日期
       if (val[1] != this.defaultDate[1]) {
         console.log('月份改变了')
         let nowYear = this.dateTimeArray[0][val[0]]
         let nowMonth = this.dateTimeArray[1][val[1]]
         // 将选择的月份对应的日期赋值给dateTimeArray
         this.dateTimeArray[2] = getMonthDay(nowYear, nowMonth)
       }
       this.defaultDate = val
     },
     // 确定时间
     confirmDate() {
       // 将选择的时间格式化返回
       this.time = generateTimeStr(this.dateTimeArray, this.defaultDate)
       this.showPickDate = false
     },
   }
 }
</script>

  1. 最后附上弹窗样式
.popup_container {
   color: #333;

   .popup_btn {
     padding: 0 30rpx 30rpx;
     display: flex;

     .btn {
       flex: 1;
       height: 90rpx;
       border-radius: 50rpx;
       display: flex;
       justify-content: center;
       align-items: center;

       &.cancel_btn {
         background-color: #CCCCCC;
         margin-right: 14rpx;
       }

       &.confirm_btn {
         background-color: #00469B;
         color: #fff;
       }
     }
   }

   .popup_title {
     padding: 30rpx 0 20rpx;
     display: flex;
     justify-content: center;
     align-items: center;
     border-bottom: 1rpx solid #eee;
   }

   .popup_picker {
     margin: 60rpx 0;
     height: 450rpx;
   }

   .picker_view {
     width: 100%;
     height: 450rpx;
   }

   .picker_item {
     line-height: 45px;
     text-align: center;
   }
 }