Vue3+vantUI3時(shí)間組件封裝過(guò)程支持選擇年以及年月日時(shí)分秒
效果圖:


代碼
<script setup name="PopupAllPicker">
const emit = defineEmits(['update:modelValue', 'confirm']);
const attrs = useAttrs();
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
values: {
type: String,
default: ''
},
title: {
type: String,
default: '請(qǐng)選擇時(shí)間'
},
valueFormat: {
type: String,
default: 'YYYY-MM-DD HH:mm:ss'
}
});
// 是否顯示彈出層
const columns = ref([]);
const Mdays = ref('');
const Dindex = ref(null);
const picker = ref(null);
// 獲取某年某月多少天
function getCountDays(year, month) {
const day = new Date(year, month, 0);
return day.getDate();
}
// 獲取年月日時(shí)分秒列信息
function getColumns() {
const strTime = props.values;
let vModuleDate;
if (props.values !== '') {
vModuleDate = new Date(strTime.replace(/-/g, '/'));
} else {
vModuleDate = new Date(); // 沒(méi)有傳入時(shí)間則默認(rèn)當(dāng)前時(shí)刻
}
const Y = vModuleDate.getFullYear();
const M = vModuleDate.getMonth();
const D = vModuleDate.getDate();
const h = vModuleDate.getHours();
const m = vModuleDate.getMinutes();
const s = vModuleDate.getSeconds();
const year = {}; // 獲取前后十年數(shù)組
year.values = [];
const CurrentDay = new Date().getFullYear();
for (let i = CurrentDay - 4; i < CurrentDay + 1; i += 1) {
year.values.push(i);
}
year.defaultIndex = year.values.indexOf(Y);
const month = {};
// 獲取12月數(shù)組
month.defaultIndex = M;
month.values = Object.keys([...Array(13)]).map((item) => {
if (+item + 1 <= 10) {
return `0${item}`;
}
if (+item + 1 === 11) {
return `${item}`;
}
return (+item + 0).toString();
});
month.values.splice(0, 1);
const days = getCountDays(Y, Mdays.value === '' ? M + 1 : Mdays.value);
const day = {}; // 創(chuàng)建當(dāng)月天數(shù)數(shù)組
day.defaultIndex = Dindex.value === null ? D - 1 : Dindex.value;
day.values = Object.keys([...Array(days + 1)]).map((item) => {
if (+item + 1 <= 10) {
return `0${item}`;
}
if (+item + 1 === 11) {
return `${item}`;
}
return (+item + 0).toString();
});
day.values.splice(0, 1);
const hour = {}; // 創(chuàng)建小時(shí)數(shù)組
hour.defaultIndex = h;
hour.values = Object.keys([...Array(24)]).map((item) => {
if (+item + 1 <= 10) {
return `0${item}`;
}
if (+item + 1 === 11) {
return `${item}`;
}
return (+item + 0).toString();
});
const mi = {}; // 創(chuàng)建分鐘數(shù)組
mi.defaultIndex = m;
mi.values = Object.keys([...Array(60)]).map((item) => {
if (+item + 1 <= 10) {
return `0${item}`;
}
if (+item + 1 === 11) {
return `${item}`;
}
return (+item + 0).toString();
});
const ss = {}; // 創(chuàng)建秒數(shù)數(shù)組
ss.defaultIndex = s;
ss.values = Object.keys([...Array(60)]).map((item) => {
if (+item + 1 <= 10) {
return `0${item}`;
}
if (+item + 1 === 11) {
return `${item}`;
}
return (+item + 0).toString();
});
// 設(shè)置默認(rèn)選項(xiàng)當(dāng)前年
if (props.valueFormat.includes('YYYY')) {
columns.value.push(year);
}
if (props.valueFormat.includes('MM')) {
columns.value.push(month); // 獲取當(dāng)月的天數(shù)
}
if (props.valueFormat.includes('DD')) {
columns.value.push(day);
}
if (props.valueFormat.includes('HH')) {
columns.value.push(hour);
}
if (props.valueFormat.includes('mm')) {
columns.value.push(mi);
}
if (props.valueFormat.includes('ss')) {
columns.value.push(ss);
}
}
function onChange(values) {
// a為所有列備選項(xiàng)值的數(shù)組
const days = getCountDays(values[0], values[1]);
const newDays = {};
newDays.values = Object.keys([...Array(days + 1)]).map((item) => {
if (+item + 1 <= 10) {
return `0${item}`;
}
if (+item + 1 === 11) {
return `${item}`;
}
return (+item + 0).toString();
});
newDays.values.splice(0, 1);
// 設(shè)置第三列的值
picker.value.setColumnValue(2, newDays.values);
// 設(shè)置第三列索引
picker.value.setColumnIndex(2, values[2] - 1);
}
// 關(guān)閉彈框
function onCancel() {
Mdays.value = '';
Dindex.value = null;
emit('update:modelValue', false);
}
// 時(shí)間選擇器確定
function onConfirm(val) {
let endVal = '';
for (let i = 0; i < columns.value.length; i += 1) {
endVal += val[i];
if (i === 2) {
endVal += ' ';
} else if (i >= 3 && i <= 5) {
endVal += ':';
} else if (i < columns.value.length - 1) {
endVal += '-';
}
}
// 判斷最后一個(gè)字符是否是分隔符
if (endVal.endsWith('-') || endVal.endsWith(':')) {
endVal = endVal.slice(0, -1); // 刪除最后一個(gè)字符
}
emit('update:modelValue', false);
emit('confirm', endVal);
}
watch(
() => props.modelValue,
(val) => {
if (!val) emit('update:modelValue');
columns.value = [];
getColumns();
}
);
watch(
() => props.values,
(val) => {
if (val === '') {
Mdays.value = '';
Dindex.value = null;
}
}
);
</script>
<template>
<!-- 彈出層 -->
<van-popup :show="modelValue" round position="bottom" teleport="body" class="!rounded-t-[6px]" @close="onCancel">
<!-- 時(shí)間選擇 -->
<van-picker
v-bind="attrs"
ref="picker"
show-toolbar
:title="title"
:columns="columns"
@change="onChange"
@cancel="onCancel"
@confirm="onConfirm"
/>
</van-popup>
</template>
<style lang="less" scoped></style>使用
<script setup>
import dayjs from 'dayjs';
import PopupAllPicker from '../components/PopupAllPicker.vue';
const data = reactive({
popupCode: '',
dateType: 'date',
dateFormatter: 'YYYY-MM-DD',
datePicker: false,
pickerDate: '' // 當(dāng)前時(shí)間選擇器的時(shí)間
});
const form = reactive({
...,
})
// 選擇器默認(rèn)范圍(當(dāng)前時(shí)間前后2年)
const minDate = dayjs().subtract(2, 'year').$d;
const maxDate = dayjs().subtract(-1, 'year').$d;
// 確認(rèn)時(shí)間
function onConfirmPicker(val) {
form[data.popupCode] = val;
}
</script>
<template>
...
<!-- 時(shí)間選擇器 -->
<PopupAllPicker
v-model="data.datePicker"
ref="popup"
:values="data.pickerDate"
:min-date="minDate"
:max-date="maxDate"
:valueFormat="data.dateFormatter"
@confirm="onConfirmPicker"
/>
</template>到此這篇關(guān)于Vue3+vantUI3時(shí)間組件封裝,支持選擇年以及年月日時(shí)分秒miao的文章就介紹到這了,更多相關(guān)Vue3 vantUI3時(shí)間組件封裝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VUE實(shí)現(xiàn)一個(gè)Flappy Bird游戲的示例代碼
這篇文章主要介紹了VUE實(shí)現(xiàn)一個(gè)Flappy Bird的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
Fragment 占位組件不生成標(biāo)簽與路由組件lazyLoad案例
這篇文章主要為大家介紹了Fragment 占位組件不生成標(biāo)簽與路由組件lazyLoad案例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
vue中的vendor.js文件過(guò)大問(wèn)題及解決
這篇文章主要介紹了vue中的vendor.js文件過(guò)大問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
Vue Object.defineProperty及ProxyVue實(shí)現(xiàn)雙向數(shù)據(jù)綁定
這篇文章主要介紹了Vue Object.defineProperty及ProxyVue實(shí)現(xiàn)雙向數(shù)據(jù)綁定,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
23個(gè)不可錯(cuò)過(guò)的Vue3實(shí)用Hook
@vueuse/core提供了豐富的功能性鉤子,使得處理常見(jiàn)的開(kāi)發(fā)任務(wù)變得更加簡(jiǎn)潔和高效,本文將詳細(xì)介紹如何在Vue3項(xiàng)目中使用?@vueuse/core及其一些極具價(jià)值的功能,需要的可以參考下2024-11-11
解決vue項(xiàng)目中出現(xiàn)Invalid Host header的問(wèn)題
這篇文章主要介紹了解決vue項(xiàng)目中出現(xiàn)"Invalid Host header"的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11

