vant實現(xiàn)自定義日期時間選擇器(年月日時分秒)
更新時間:2025年12月25日 08:26:17 作者:無心使然云中漫步
使用vant作為UI組件時,需要一個日期時間選擇器,vant中有Dateicker和TimePicker,可以將兩個組件組合封裝使用,下面就來詳細(xì)的介紹一下
1 背景
使用vant作為UI組件時,需要一個日期時間選擇器,vant中有Dateicker和TimePicker,可以將兩個組件組合封裝使用,但是處理傳入?yún)?shù)和傳出參數(shù)稍顯麻煩,所以使用Picker封裝一個簡單的日期時間選擇器
2 要求
- 可以傳入初始值
- 可以選擇年,年月,年月日,年月日時,年月日時分,年月日時分秒
- 可以限定選擇的最大日期和最小日期

3 實現(xiàn)
// DateTimePicker.vue
<template>
<van-picker
ref="picker"
title="請選擇時間"
:columns="columns"
@change="handleChange"
@cancel="handleCancel"
@confirm="handleConfirm"
v-model="values"
/>
</template>
<script setup lang="ts">
const props = defineProps({
// 顯示的列數(shù)量共6列(年月日時分秒)
columnCount: {
type: Number,
default: 6,
},
// 可以選擇的最小日期
minDate: {
type: Date,
default: new Date(new Date().getFullYear() - 10, 1, 1, 0, 0, 0),
},
// 可以選擇的最大日期
maxDate: {
type: Date,
default: new Date(new Date().getFullYear() + 10, 11, 31, 23, 59, 59),
},
});
const values = defineModel({
get(val) {
let param = val;
if (Array.isArray(param)) {
if (param.length > 0) {
return param.map(i => i.toString().padStart(2, '0'));
}
param = new Date();
} else if (!param) {
param = new Date();
}
const date = new Date(param);
const Y = date.getFullYear().toString();
const M = (date.getMonth() + 1).toString().padStart(2, '0'); //實際月份
const D = date.getDate().toString().padStart(2, '0');
const h = date.getHours().toString().padStart(2, '0');
const m = date.getMinutes().toString().padStart(2, '0');
const s = date.getSeconds().toString().padStart(2, '0');
return [Y, M, D, h, m, s];
},
});
const columns = ref([]); //所有時間列
const maxDateArray = computed(() => getDateArray(props.maxDate));
onBeforeMount(() => {
getColumns();
});
const getColumns = () => {
const options = [
{
radix: props.maxDate.getFullYear() - props.minDate.getFullYear() + 1,
base: props.minDate.getFullYear(),
},
{
radix: 12,
base: 1,
},
{
radix: getCountDays(values.value[0], values.value[1]),
base: 1,
},
{
radix: 24,
base: 0,
},
{
radix: 60,
base: 0,
},
{
radix: 60,
base: 0,
},
].slice(0, props.columnCount);
options.forEach((item, index) => {
columns.value.push(fillData(index, item.radix, item.base));
});
};
const fillData = (index, radix, baseNum = 0) => {
return Object.keys(new Array(radix).fill()).map(item => ({
text: (Number(item) + baseNum).toString().padStart(2, '0'),
value: (Number(item) + baseNum).toString().padStart(2, '0'),
disabled: Number(item) + baseNum > maxDateArray.value[index],
}));
};
const getCountDays = (year, month) => {
//獲取某年某月最后1天
return new Date(year, month, 0).getDate();
};
const getDateArray = param => {
const date = new Date(param);
const Y = date.getFullYear();
const M = date.getMonth() + 1; //實際月份
const D = date.getDate();
const h = date.getHours();
const m = date.getMinutes();
const s = date.getSeconds();
return [Y, M, D, h, m, s];
};
const handleChange = ({ selectedValues, columnIndex }) => {
const dateArray = [...selectedValues].map((i, idx) => {
if (idx == 1) {
return Number(i) - 1;
}
return Number(i);
});
const maxDate = maxDateArray.value.map((i, idx) => {
if (idx == 1) {
return Number(i) - 1;
}
return i;
});
if (columnIndex <= 1 && columns.value.length > 2) {
const lastDay = getCountDays(Number(selectedValues[0]), Number(selectedValues[1]));
columns.value[2] = fillData(2, lastDay, 1);
if (lastDay < Number(selectedValues[2])) {
//切換年列或者月列時,因為每月的天可能不同,所以天列需要重置
values.value = values.value
.map((item, idx) => {
if (idx === 2) {
return lastDay.toString();
}
return item;
})
.slice(0, props.columnCount);
}
}
if (
new Date(...dateArray.slice(0, columnIndex + 1)).getTime() <
new Date(...maxDate.slice(0, columnIndex + 1)).getTime()
) {
for (let i = columnIndex + 1; i < columns.value.length; i++) {
columns.value[i].forEach(k => {
k.disabled = false;
});
}
} else {
for (let i = columnIndex + 1; i < columns.value.length; i++) {
columns.value[i].forEach(k => {
if (Number(k.value) > maxDateArray.value[i]) {
k.disabled = true;
}
});
}
if (new Date(...dateArray).getTime() > new Date(...maxDate).getTime()) {
values.value = maxDateArray.value.slice(0, props.columnCount);
}
}
};
const handleCancel = () => {
emit('cancel');
};
const handleConfirm = ({ selectedValues }) => {
emit(
'confirm',
(selectedValues.slice(0, 3).join('-') + ' ' + selectedValues.slice(3).join(':')).trim()
);
};
const emit = defineEmits(['confirm', 'cancel']);
</script>
// index.vue
<template>
<van-button type="primary" @click="handleClick">選擇日期</van-button>
<van-popup v-model:show="showPicker" round position="bottom">
<DateTimePicker
v-model="values"
:maxDate="maxDate"
@cancel="handleCancel"
@confirm="handleConfirm"
/>
</van-popup>
</template>
<script setup lang="ts">
const maxDate = new Date();
const showPicker = ref(false);
const values = ref(['2025','12','23','12','01','12']);//設(shè)置初始日期時間
const handleConfirm = () => {
//點擊確定的事件
showPicker.value = false;
}
const handleCancel = () => {
//點擊取消的事件,比如關(guān)閉彈框
showPicker.value = false;
}
const handleClick = () => {
showPicker.value = true;
}
</script>
到此這篇關(guān)于vant實現(xiàn)自定義日期時間選擇器(年月日時分秒)的文章就介紹到這了,更多相關(guān)vant 日期時間選擇器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解element-ui級聯(lián)菜單(城市三級聯(lián)動菜單)和回顯問題
這篇文章主要介紹了詳解element-ui級聯(lián)菜單(城市三級聯(lián)動菜單)和回顯問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10

