vue3 setup+Taro3 调用原生小程序自定义年月日时分多列选择器,NutUI改造

vue3 setup+Taro3 调用原生小程序自定义年月日时分多列选择器,NutUI改造

NutUI 有日期时间选择器,但是滑动效果太差,卡顿明显。换成 原生小程序 很顺畅

在这里插入图片描述

上代码:

<template>
  <view>
    <picker
      mode="multiSelector"
      @change="confirmPicker"
      @columnChange="scrollColumnChange"
      :value="columnVal"
      :range="multiArray"
    >
      <nut-cell
        title="选择时间"
        :desc="showVal"
        @click="copyColumnVal = columnVal"
      ></nut-cell>
      <!-- <view @click="copyColumnVal = columnVal">
        当前选择:{
    
    {
    
     showVal }}
      </view> -->
    </picker>
  </view>
</template>

<script setup>
import {
    
     ref, onMounted, watch } from "vue";
const multiArray = ref(undefined); // 列可选列表
const columnVal = ref(undefined); // 列当前选中值
const copyColumnVal = ref(undefined); // 记录滚动中数据
const showVal = ref(undefined); // 显示:后年月日时分

// 个位数时 补0
const add0 = (num) => String(num > 9 ? num : "0" + num);

// 判断平年闰年
const resYearType = (year) =>
  (year % 4 == 0) & (year % 100 != 0) || year % 400 == 0;

// 获取当前时间
const getNowT = (timeInfo) => {
    
    
  // timeInfo 为 年月日字符串 或者 时间戳
  var nowT = new Date(timeInfo);
  return {
    
    
    year: nowT.getFullYear(),
    month: nowT.getMonth() + 1,
    day: nowT.getDate(),
    hour: nowT.getHours(),
    minute: nowT.getMinutes(),
    second: nowT.getSeconds(),
  };
};

// 设置当前时间 - columnVal:每列索引数组集合
function setNowTime(timeStr) {
    
    
  const timeObj = getNowT(timeStr); // timeObj 为: { year, month, day... }
  const {
    
     year, month, day, hour, minute } = timeObj;
  // 获取滚动列表数据
  const [
    years,
    months,
    days,
    hours,
    minutes,
  ] = multiArray.value;
  const yearsIdx = years.findIndex((item) => item == year);
  const monthsIdx = months.findIndex((item) => item == month);
  const daysIdx = days.findIndex((item) => item == day);
  const hoursIdx = hours.findIndex((item) => item == hour);
  const minutesIdx = minutes.findIndex((item) => item == minute);
  columnVal.value = [yearsIdx, monthsIdx, daysIdx, hoursIdx, minutesIdx];
  showVal.value = `${
      
      year}/${
      
      add0(month)}/${
      
      add0(day)} ${
      
      add0(hour)}:${
      
      add0(
    minute
  )}`;

  // 根据当前时间,初始化可选择日期时间
  setDaysList(columnVal.value)
}

// 初始化时间
function initColumn(daysNum = 31) {
    
    
  // 年
  const yearStart = 2000; // 年 - 开始时间
  const yearLength = 100; // 年 - 列表长度
  const years = Array.from({
    
     length: yearLength }).map((i, idx) =>
    add0((idx += yearStart))
  );

  // 月
  const months = Array.from({
    
     length: 12 }).map((i, idx) => add0((idx += 1)));

  // 日
  const days = Array.from({
    
     length: daysNum }).map((i, idx) =>
    add0((idx += 1))
  );

  // 时
  const hours = Array.from({
    
     length: 24 }).map((i, idx) => add0((idx += 0)));

  // 分
  const minutes = Array.from({
    
     length: 60 }).map((i, idx) => add0((idx += 0)));

  multiArray.value = [
    years,
    months,
    days,
    hours,
    minutes,
  ];
}

// 滚动设置可选天数 28 - 29 - 30 - 31
function setDays(daysNum = 31) {
    
    
  multiArray.value[2] = Array.from({
    
     length: daysNum }).map((i, idx) =>
    add0((idx += 1))
  );

  // 深拷贝下,否则不动态修改列
  multiArray.value = JSON.parse(JSON.stringify(multiArray.value));
}

// 修改每月的天数
function setDaysList(columnArr) {
    
    
  const [yearsIdx, monthsIdx] = columnArr;
  const [years] = multiArray.value;
  // 当选择2月
  if (monthsIdx == 1) {
    
    
    // 如果闰年
    if (resYearType(years[yearsIdx])) {
    
    
      setDays(29);
    } else {
    
    
      setDays(28);
    }
  } else if ([1, 3, 5, 7, 8, 10, 12].includes(monthsIdx + 1)) {
    
    
    // 当选择1, 3, 5, 7, 8, 10, 12月
    setDays(31);
  } else {
    
    
    setDays(30);
  }
}

// 确认选中结果
function confirmPicker(e) {
    
    
  columnVal.value = e.detail.value;
  const [yearsIdx, monthsIdx, daysIdx, hoursIdx, minutesIdx] = e.detail.value;
  const [years, months, days, hours, minutes] = multiArray.value;
  showVal.value = `${
      
      years[yearsIdx]}/${
      
      months[monthsIdx]}/${
      
      days[daysIdx]} ${
      
      hours[hoursIdx]}:${
      
      minutes[minutesIdx]}`;
}

// 滚动事件(未点击确定)
function scrollColumnChange(e) {
    
    
  const {
    
     column, value } = e.detail;
  copyColumnVal.value[column] = value;
  setDaysList(copyColumnVal.value);

  console.log("修改的列为", column, ",值为", value);
}

// 初始化
onMounted(() => {
    
    
  initColumn();

  // 回显时间
  setNowTime(new Date().getTime());
});


// 监听传递日期
const props = defineProps({
    
    
  propsTime: {
    
    
    type: String,
    default: ''
  }
})
watch(props.propsTime, (newValue, oldValue) => {
    
    
  console.log('值发生了变更', newValue, oldValue);
  // 回显时间
  setNowTime(newValue);
});

</script>

若需要自定义年开始时间,见 initColumn 方法

在这里插入图片描述

如作为组件,通过父级传递,可使用:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44461275/article/details/132229663