使用方法
<date-picker v-if="mode == 'date'" class="w-picker-wrapper" :from-data="fromData" :startYear="startYear"
:endYear="endYear" :value="value" :fields="fields" :item-height="itemHeight" :current="current"
:disabled-after="disabledAfter" @change="handlerChange" @touchstart="touchStart"
@touchend="touchEnd"></date-picker>
组件代码
<template>
<view class="w-picker-view">
<picker-view v-if="fields == 'year'" class="d-picker-view" :indicator-style="itemHeight" :value="pickerVal.list"
@change="bindChange">
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in years.list" :key="index">{{ item }}{{$t('年')}}</view>
</picker-view-column>
</picker-view>
<picker-view v-else-if="fields == 'month'" class="d-picker-view" :indicator-style="itemHeight"
:value="pickerVal.list" @change="bindChange">
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in years.list" :key="index">{{ item }}{{$t('年')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in months.list" :key="index">{{ item }}{{$t('月')}}</view>
</picker-view-column>
</picker-view>
<picker-view v-if="fields == 'day'" class="d-picker-view" :indicator-style="itemHeight" :value="pickerVal.list"
@change="bindChange">
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in years.list" :key="index">{{ item }}{{$t('年')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in months.list" :key="index">{{ item }}{{$t('月')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in days.list" :key="index">{{ item }}{{$t('日')}}</view>
</picker-view-column>
</picker-view>
<picker-view v-else-if="fields == 'hour'" class="d-picker-view" :indicator-style="itemHeight" :value="pickerVal.list"
@change="bindChange">
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in years.list" :key="index">{{ item }}{{$t('年')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in months.list" :key="index">{{ item }}{{$t('月')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in days.list" :key="index">{{ item }}{{$t('日')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in hours.list" :key="index">{{ item }}{{$t('时')}}</view>
</picker-view-column>
</picker-view>
<picker-view v-else-if="fields == 'minute'" class="d-picker-view" :indicator-style="itemHeight" :value="pickerVal.list" @change="bindChange">
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in years.list" :key="index">{{ item }}{{$t('年')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in months.list" :key="index">{{ item }}{{$t('月')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in days.list" :key="index">{{ item }}{{$t('日')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in hours.list" :key="index">{{ item }}{{$t('时')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in minutes.list" :key="index">{{ item }}{{$t('分')}}</view>
</picker-view-column>
</picker-view>
<picker-view v-else class="d-picker-view" :indicator-style="itemHeight" :value="pickerVal.list" @change="bindChange">
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in years.list" :key="index">{{ item }}{{$t('年')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in months.list" :key="index">{{ item }}{{$t('月')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in days.list" :key="index">{{ item }}{{$t('日')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in hours.list" :key="index">{{ item }}{{$t('时')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in minutes.list" :key="index">{{ item }}{{$t('分')}}</view>
</picker-view-column>
<picker-view-column>
<view class="w-picker-item" v-for="(item, index) in seconds.list" :key="index">{{ item }}{{$t('秒')}}</view>
</picker-view-column>
</picker-view>
</view>
</template>
<script setup>
import {
defineProps,
reactive,
ref,
watch,
onBeforeMount,
defineEmits,
nextTick
} from 'vue'
import {
dayjs
} from "@/uni_modules/iRainna-dayjs/js_sdk/dayjs.min.js";
const emits = defineEmits(['change'])
const props = defineProps({
startYear: {
type: [String, Number],
default: '2010/01/01 00:00',
},
endYear: {
type: [String, Number],
default: '2050/12/31 23:59',
},
fromData: {
// 自定义日期选择器返回格式
type: String,
default: '',
},
value: {
type: [String, Number],
default: '',
},
itemHeight: {
type: String,
default: '44px',
},
fields: {
type: String,
default: 'day',
},
});
const baseArr = {
list: ['', '']
};
var nowdate = ref('');
var presentTime = reactive(new Date());
var years = reactive({
list: ['', '']
});
var months = reactive({
list: ['', '']
});
var days = reactive({
list: ['', '']
});
var hours = reactive({
list: ['', '']
});
var minutes = reactive({
list: ['', '']
});
var seconds = reactive({
list: ['', '']
});
var days28 = reactive([]);
var pickerVal = reactive({
list:[]
});
var startObj = reactive({
months: [],
days: []
});
var endObj = reactive({
months: [],
days: []
});
var changeDisabled = ref(false);
var moveFlag = ref(false);
var showCover = ref(false);
var hasChange = ref(false);
watch(() => props.startYear, () => {
setStartEnd()
let date = props.value ? props.value : new Date()
initCurr(date)
})
watch(() => props.endYear, () => {
setStartEnd()
let date = props.value ? props.value : new Date()
initCurr(date)
})
watch(() => props.value, (val, oval) => {
let date = val ? val : new Date();
initCurr(date)
let {
y,
m,
d,
h,
minu,
sec
} = trimDate(props.value)
let trimN = trimNum
nowdate = `${y}-${trimN(m)}-${trimN(d)} ${trimN(h)}:${trimN(minu)}:${trimN(sec)}`
})
onBeforeMount(() => {
days28 = setArray(1, 28)
setStartEnd()
if (props.value) {
const {
y,
m,
d,
h,
minu,
sec
} = trimDate(props.value)
const trimN = trimNum
nowdate = `${y}-${trimN(m)}-${trimN(d)} ${trimN(h)}:${trimN(minu)}:${trimN(sec)}`
}
const date = props.value ? props.value : new Date()
initCurr(date)
nextTick(() => {
confirm()
})
});
// 当滚动选择
const bindChange = (e) => {
if (changeDisabled.value) return
changeDisabled.value = true
const prev = pickerVal.list
const val = e.detail.value
const y = years.list[val[0]] ? years.list[val[0]] : years.list[years.list.length - 1]
const m = months.list[val[1]] ? months.list[val[1]] : months.list[months.list.length - 1]
const d = days.list[val[2]] ? days.list[val[2]] : days.list[days.list.length - 1]
const h = hours.list[val[3]] >= 0 ? hours.list[val[3]] : hours.list[hours.list.length - 1]
const minu = minutes.list[val[4]] >= 0 ? minutes.list[val[4]] : minutes.list[minutes.list.length - 1]
const sec = seconds.list[val[5]] >= 0 ? seconds.list[val[5]] : seconds.list[seconds.list.length - 1]
const date = `${y}/${m}/${d} ${h}:${minu}:${sec}`
if (prev[1] != val[1]) {
initCurr(date, m, d)
} else {
initCurr(date)
}
}
// 点击确定
const confirm = () => {
const val = pickerVal.list
const trimN = trimNum
let date = ''
let obj = {}
switch (props.fields) {
case 'year':
date = `${years.list[val[0]]}`
obj = {
year: years.list[val[0]],
}
break
case 'month':
date = `${years.list[val[0]]}-${trimN(months.list[val[1]])}`
obj = {
year: years.list[val[0]],
month: months.list[val[1]],
}
break
case 'day':
date = `${years.list[val[0]]}-${trimN(months.list[val[1]])}-${trimN(days.list[val[2]])}`
obj = {
year: years.list[val[0]],
month: months.list[val[1]],
day: days.list[val[2]],
}
break
case 'hour':
date =
`${years.list[val[0]]}-${trimN(months.list[val[1]])}-${trimN(days.list[val[2]])} ${trimN(hours.list[val[3]])}`
obj = {
year: years.list[val[0]],
month: months.list[val[1]],
day: days.list[val[2]],
hour: hours.list[val[3]],
}
break
case 'minute':
date =
`${years.list[val[0]]}-${trimN(months.list[val[1]])}-${trimN(days.list[val[2]])} ${trimN(hours.list[val[3]])}:${trimN(minutes.list[val[4]])}`
obj = {
year: years.list[val[0]],
month: months.list[val[1]],
day: days.list[val[2]],
hour: hours.list[val[3]],
minute: minutes.list[val[4]],
}
break
default:
date =
`${years.list[val[0]]}-${trimN(months.list[val[1]])}-${trimN(days.list[val[2]])} ${trimN(hours.list[val[3]])}:${trimN(minutes.list[val[4]])}:${trimN(seconds.list[val[5]])}`
obj = {
year: years.list[val[0]],
month: months.list[val[1]],
day: days.list[val[2]],
hour: hours.list[val[3]],
minute: minutes.list[val[4]],
second: seconds.list[val[5]],
}
break
}
if (props.fromData.trim()) date = dayjs(date).format(props.fromData)
nowdate = date
emits('change', {
result: date,
value: date,
obj: obj,
})
}
const setDays = (year, month, start = 1) => {
let newDays = []
const monthReg = /^4|6|9|11$/
let maxDay = ''
if (monthReg.test(month)) {
maxDay = 30
} else if (month === 2) {
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
maxDay = 29
} else {
maxDay = 28
}
} else {
maxDay = 31
}
newDays = setArray(start, maxDay)
return newDays
}
// 设置最大最小月日时分
const setStartEnd = () => {
const {
sy,
ey,
sm,
em,
sd,
ed,
sh,
eh,
sminu,
eminu,
ssec,
esec
} = getSE()
years.list = setArray(sy, ey)
// 设置最大最小月
if (sy === ey) {
startObj.months = endObj.months = setArray(sm, em)
} else {
startObj.months = setArray(sm, 12)
endObj.months = setArray(1, em)
}
// 设置最大最小日
if (sy === ey && sm === em) {
startObj.days = endObj.days = setArray(sd, ed)
} else {
startObj.days = setDays(sy, sm, sd)
endObj.days = setArray(1, ed)
}
// 设置最大最小时
if (sy === ey && sm === em && sd === ed) {
startObj.hours = endObj.hours = setArray(sh, eh)
} else {
startObj.hours = setArray(sh, 23)
endObj.hours = setArray(0, eh)
}
// 设置最大最小分钟
if (sy === ey && sm === em && sd === ed && sh === eh) {
startObj.minutes = endObj.minutes = setArray(sminu, eminu)
} else {
startObj.minutes = setArray(sminu, 59)
endObj.minutes = setArray(0, eminu)
}
// 设置最大最小秒
if (sy === ey && sm === em && sd === ed && sh === eh && sminu === eminu) {
startObj.seconds = endObj.seconds = setArray(ssec, esec)
} else {
startObj.seconds = setArray(ssec, 59)
endObj.seconds = setArray(0, esec)
}
}
// 初始化选中项
const initCurr = (val, month, day) => {
const {
start,
end,
sy,
ey,
sm,
em,
sd,
ed,
sh,
eh,
sminu,
eminu,
ssec,
esec
} = getSE()
const {
val: curr,
y: cy,
m: cm,
d: cd,
h: ch,
minu: cminu,
sec: csec
} = trimDate(val, month, day)
let cyi = years.list.indexOf(cy)
let cmi = 0
let cdi = 0
let chi = 0
let cminui = 0
let cseci = 0
let endSIFlag = true // 是否在最后统一设置index
if (curr.getTime() >= end.getTime()) {
// 值大于等于结束时间
// console.log(11)
months.list = endObj.months
days.list = endObj.days
hours.list = endObj.hours
minutes.list = endObj.minutes
seconds.list = endObj.seconds
cyi = years.list.length - 1
cmi = months.list.length - 1
cdi = days.list.length - 1
chi = hours.list.length - 1
cminui = minutes.list.length - 1
cseci = seconds.list.length - 1
endSIFlag = false
} else if (curr.getTime() <= start.getTime()) {
// 值小于等于开始时间
// console.log(22)
months.list = startObj.months
days.list = startObj.days
hours.list = startObj.hours
minutes.list = startObj.minutes
seconds.list = startObj.seconds
cyi = cmi = cdi = chi = cminui = cseci = 0
endSIFlag = false
} else if (cy === ey && cm === em && cd === ed && ch === eh) {
// 值与结束时间年/月/日/时相同
// console.log(222)
months.list = endObj.months
days.list = endObj.days
hours.list = endObj.hours
minutes.list = endObj.minutes
seconds.list = endObj.seconds
} else if (cy === ey && cm === em && cd === ed) {
// 值与结束时间年/月/日相同
// console.log(111)
months.list = endObj.months
days.list = endObj.days
hours.list = endObj.hours
// console.log(hours)
minutes.list = setArray(0, 59)
seconds.list = setArray(0, 59)
} else if (cy === ey && cm === em) {
// 值与结束时间年、月相同
// console.log(33)
months.list = endObj.months
days.list = endObj.days
hours.list = setArray(0, 23)
minutes.list = setArray(0, 59)
seconds.list = setArray(0, 59)
} else if (cy === ey) {
// 值与结束时间年份相同
// console.log(44)
months.list = endObj.months
days.list = setDays(cy, cm)
hours.list = setArray(0, 23)
minutes.list = setArray(0, 59)
seconds.list = setArray(0, 59)
} else if (cy === sy && cm === sm && cd === sd && ch === sh) {
// 值与开始时间年/月/日/时相同
// console.log(99)
months.list = startObj.months
days.list = startObj.days
hours.list = startObj.hours
minutes.list = startObj.minutes
seconds.list = startObj.seconds
} else if (cy === sy && cm === sm && cd === sd) {
// 值与开始时间年/月/日相同
// console.log(88)
months.list = startObj.months
days.list = startObj.days
hours.list = startObj.hours
minutes.list = setArray(0, 59)
seconds.list = setArray(0, 59)
} else if (cy === sy && cm === sm) {
// 值与开始时间年、月相同
// console.log(55)
months.list = startObj.months
days.list = startObj.days
hours.list = setArray(0, 23)
minutes.list = setArray(0, 59)
seconds.list = setArray(0, 59)
} else if (cy === sy) {
// 值与开始时间年份相同
// console.log(66)
months.list = startObj.months
days.list = setDays(cy, cm)
hours.list = setArray(0, 23)
minutes.list = setArray(0, 59)
seconds.list = setArray(0, 59)
} else {
// 值与开始时间、结束时间不同年月
// console.log(77)
months.list = setArray(1, 12)
days.list = setDays(cy, cm)
hours.list = setArray(0, 23)
minutes.list = setArray(0, 59)
seconds.list = setArray(0, 59)
}
if (endSIFlag) {
const di = days.list.indexOf(cd)
cmi = months.list.indexOf(cm)
cdi = di === -1 ? days.list.length - 1 : di
chi = hours.list.indexOf(ch)
cminui = minutes.list.indexOf(cminu)
cseci = seconds.list.indexOf(csec)
}
console.log(pickerVal.list);
setTimeout((item) => {
pickerVal.list = [cyi, cmi, cdi, chi, cminui, cseci]
confirm()
changeDisabled.value = false
}, 50)
// $nextTick(() => {
// pickerVal.list = [cyi, cmi, cdi, chi, cminui]
// confirm()
// changeDisabled.value = false
// // showCover.value = false
// // hasChange.value = false
// })
}
// 设置开始/结束时间相关变量
const getSE = () => {
let s = props.startYear
let e = props.endYear
s = s ? s : '2010-01-01 00:00:00'
e = e ? e : '2050-12-31 23:59:59'
const {
val: start,
y: sy,
m: sm,
d: sd,
h: sh,
minu: sminu,
sec: ssec
} = trimDate(s)
const {
val: end,
y: ey,
m: em,
d: ed,
h: eh,
minu: eminu,
sec: esec
} = trimDate(e)
return {
start,
sy,
sm,
sd,
sh,
sminu,
ssec,
end,
ey,
em,
ed,
eh,
eminu,
esec
}
}
const trimDate = (val, month, day) => {
// const reg = /^\d{4}-\d{1,2}-\d{1,2}( \d{1,2}:\d{1,2})?(:\d{1,2})?$/
let curr = ''
if (val == '现在') {
curr = presentTime
} else {
if (typeof val === 'string') {
curr = dayjs(val,
['YYYY', 'YYYY-MM-DD', 'YYYY-MM-DD HH', 'YYYY-MM-DD HH:mm', props.fromData ? props.fromData : 'YYYY-MM-DD HH:mm:ss'], 'es', true).$d
} else {
curr = new Date(val)
}
}
return {
val: curr,
y: curr.getFullYear(),
m: month ? month : curr.getMonth() + 1,
d: day ? day : curr.getDate(),
h: curr.getHours(),
minu: curr.getMinutes(),
sec: curr.getSeconds(),
}
}
// 获取一个范围内的整数,返回数组
const setArray = (start, end) => {
const arr = []
for (let i = start; i <= end; i++) {
arr.push(i)
}
return arr
}
// 将数字转换成两位
const trimNum = (num) => {
num = num >= 10 ? num : `0${num}`
return num
}
</script>
<style scoped>
@import './w-picker.css';
</style>
2***@qq.com (作者)
好了爹
2024-07-15 15:28