123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- <template>
- <div class="dateTimeRangeBox">
- <van-field
- :label="label"
- :placeholder="placeholder"
- v-model="currentDateTime"
- readonly
- @touchstart="clickHandler"
- />
- <van-popup class="detail-popup" v-model:show="popupShow" position="bottom">
- <van-picker
- v-model="selectDateTime"
- title="时间选择"
- :columns="dateTimeRangeColumns"
- @change="changeHandle"
- @confirm="confirmHandle"
- @cancel="cancelHandle"
- />
- </van-popup>
- </div>
- </template>
- <script lang="ts" setup>
- defineOptions({
- name: 'DateTimeRange'
- })
- const props = defineProps<{
- label: string
- placeholder: string
- modelValue: string
- }>()
- const emit = defineEmits<{
- (e: 'update:modelValue', payload: any): void
- (e: 'change', payload: string):void
- }>()
- const currentYear: number = new Date().getFullYear();
- const currentMonth: number = new Date().getMonth()+1;
- const currentDay: number = new Date().getDate();
- const selectYear = ref<string>(currentYear.toString());
- const selectMonth = ref<string>(currentMonth.toString());
- const currentDateTime = ref<string>('')
- const selectDateTime = ref<string[]>([])
- const defaultDateTime: string[] = [currentYear.toString(), fillZero(currentMonth), fillZero(currentDay), '00', '00']
- if (props.modelValue) {
- selectDateTime.value = formatDateTimeArr(props.modelValue);
- currentDateTime.value = props.modelValue
- } else {
- selectDateTime.value = defaultDateTime
- }
- watch(() => props.modelValue, (newVal) => {
- if(!newVal){
- currentDateTime.value = ''
- selectDateTime.value = defaultDateTime
- return;
- }
- currentDateTime.value = newVal
- const newArr = formatDateTimeArr(newVal);
- selectDateTime.value = newArr
- selectYear.value = newArr[0].toString()
- selectMonth.value = newArr[1].toString()
- setMonthByDay(newArr[0],newArr[1]);
- })
- /***
- * 固定统计年、月、时、分数据
- */
- const yearList: string[] = []
- const monthList: string[] = []
- for (let i = 2012; i < currentYear + 5; i++){
- yearList.push(i.toString())
- }
- for (let i = 1; i <= 12; i++){
- monthList.push(fillZero(i));
- }
- const houseList = [];
- for (let i = 0; i <= 23; i++){
- houseList.push(fillZero(i));
- }
- const minuteList = ['00', '30']
- const dateTimeRangeColumns = reactive([
- yearList.map(val => {
- return {text: val, value: val}
- }),
- monthList.map(val => {
- return {text: val, value: val}
- }),
- [],
- houseList.map(val => {
- return {text: val, value: val}
- }),
- minuteList.map(val => {
- return {text: val, value: val}
- }),
- ]);
- /***
- * 日单独处理,每个月日期不一样
- */
- function getDaysInMonth(year: number|string, month: number|string) {
- return new Date(year as number, month as number, 0).getDate();
- }
- function setMonthByDay(year: number|string, month: number|string) {
- const day = getDaysInMonth(year, month);
- const dayList: any[] = [];
- for (let i = 1; i <= day; i++){
- const val = fillZero(i);
- dayList.push({text: val, value: val});
- }
- dateTimeRangeColumns[2] = dayList;
- }
- function fillZero(num: number): string {
- const num2 = Number(num);
- return num < 10 ? "0" + num2.toString() : num2.toString()
- }
- /***
- * 格式化YYYY-MM-DD HH:MM:SS转成[yyy, mm, dd, hh, mm, dd]
- */
- function formatDateTimeArr(dateTime: string): string[] {
- if (!dateTime){
- console.warn('formatDateTimeArr方法参数dateTime值不能为空!')
- return []
- }
- const dateTimeArr = dateTime.split(' ');
- if (dateTimeArr.length < 2) {
- throw new Error('dateTime格式不正确! 请符合:YYYY-MM-DD HH:MM:SS');
- }
- const dateArr: string[] = dateTimeArr[0].split('-');
- const timeArr: string[] = dateTimeArr[1].split(':');
- return dateArr.concat(timeArr) as string[];
- }
- /**
- * 格式化[yyy, mm, dd, hh, mm, dd]转成 YYYY-MM-DD HH:MM:SS
- **/
- function formatDateTimeByArr(arr: string[]): string {
- if (!arr || arr.length === 0) {
- console.warn('formatDateTimeByArr方法参数arr值不能为空!')
- return ''
- }
- const dateArr: string[] = []
- arr[0] ? dateArr.push(arr[0]) : null
- arr[1] ? dateArr.push(arr[1]) : null
- arr[2] ? dateArr.push(arr[2]) : null
- const timeArr: string[] = []
- arr[3] ? timeArr.push(arr[3]) : null
- arr[4] ? timeArr.push(arr[4]) : null
- arr[5] ? timeArr.push(arr[5]) : null
- return dateArr.join('-') +' ' + timeArr.join(':')
- }
- setMonthByDay(currentYear, currentMonth);
- const changeHandle = (val: any) => {
- const arr = val.selectedValues;
- if (selectYear.value !== arr[0] || selectMonth.value !== arr[1]) {
- setMonthByDay(arr[0], arr[1]);
- selectYear.value = arr[0];
- selectMonth.value = arr[1];
- const dateTimeStr:string = formatDateTimeByArr(arr);
- currentDateTime.value = dateTimeStr
- emit('update:modelValue', dateTimeStr)
- }
- }
- const confirmHandle = () => {
- const dateTimeStr:string = formatDateTimeByArr(selectDateTime.value);
- currentDateTime.value = dateTimeStr
- emit('update:modelValue', dateTimeStr)
- emit('change', dateTimeStr)
- popupShow.value = false;
- }
- const cancelHandle = () => {
- popupShow.value = false;
- }
- const popupShow = ref<boolean>(false)
- const clickHandler = () => {
- const time = setTimeout(() => {
- popupShow.value = !popupShow.value
- clearTimeout(time)
- }, 200)
- }
- </script>
- <style lang="scope" scoped>
- </style>
|