vue3 setup+Taro3 調用原生小程序自定義年月日時分多列選擇器,NutUI改造
NutUI 有日期時間選擇器,但是滑動效果太差,卡頓明顯。換成 原生小程序 很順暢
上代碼:
<template><view><pickermode="multiSelector"@change="confirmPicker"@columnChange="scrollColumnChange":value="columnVal":range="multiArray"><nut-celltitle="選擇時間":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 方法
如作為組件,通過父級傳遞,可使用: