vue3+ts封装Date-Picker时间插件

Date-Picker时间插件封装:

<template>
    <div class="date-picker">
        <div class="date-picker-box">
            <div class="date-picker-box-header">
                <div class="date-picker-box-header-prev" @click="preMon">{{ '<<' }}</div>
                <div class="date-picker-box-header-year">{{ year }}{{ month }}</div>
                <div class="date-picker-box-header-next" @click="nextMon">{{ '>>' }}</div>
            </div>
            <div class="date-picker-box-content">
                <div class="date-picker-box-content-week">
                    <div class="date-picker-box-content-weekday"></div>
                    <div class="date-picker-box-content-weekday"></div>
                    <div class="date-picker-box-content-weekday"></div>
                    <div class="date-picker-box-content-weekday"></div>
                    <div class="date-picker-box-content-weekday"></div>
                    <div class="date-picker-box-content-weekday"></div>
                    <div class="date-picker-box-content-weekday"></div>
                </div>
                <div class="date-picker-box-content-cont">
                    <div class="date-picker-box-content-cont-day" v-for="(item, index) in pickerDate" :key="index" :class="{ outfocus: item.outfocus, today: item.showday, start: showStartEnvfun(item.dateNum, item.outfocus), end: showEndEnvfun(item.dateNum, item.outfocus), black: showBlack(item.dateNum, item.outfocus), half: showHalffun(item.dateNum, item.outfocus) }" @click="checkDay(item.dateNum, item.outfocus)">
                        {{ item.dateNum }}
                    </div>
                </div>
            </div>
            <div class="date-picker-box-footer">
                <div class="date-picker-box-footer-today">今天</div>
                <div class="date-picker-box-footer-start">开始</div>
                <div class="date-picker-box-footer-end">结束</div>
            </div>
            <div class="confim">确定</div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue';
type Pinks = {
    dateNum: number;
    outfocus: boolean;
    showday?: boolean;
};
let year = ref<number>(0); // 展示的年
let month = ref<number>(0); // 展示的月
let startEnv = ref<string>(''); // 开始日期
let endEnv = ref<string>(''); // 结束日期
let today = ref<number>(0); // 当天
let pickerDate = reactive<Pinks[]>([]); // 选择日期

// 两个日期之间间隔多少天
const getDatePeriod = (sDate1: string, sDate2: string) => {
    // 获得两个时间的时间戳
    let oDate1 = new Date(sDate1).getTime();
    let oDate2 = new Date(sDate2).getTime();
    // 把相差的毫秒数转换为天数
    let iDays = Math.floor(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 / 24);
    return iDays;
};
// 获得每个月的天数
const getMonthLen = (year: number, month: number) => {
    // 获取本月天数
    return new Date(year, month, 0).getDate();
    // 理解:new Date()构造函数的定义:new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);
    // month 参数,是指月份,从 0 开始,也就是说,0 表示 1月,9表示 10月
    // day 参数,是指月份中的某一天,从 1 开始,也就是说 1 就是月份中的第一天,2就是第二天,**0 是不在取值范围内的**
    // 在es规范中穿件一个日期的过程是:
    // 1、将传来的日期实例化,会先获取指定年月的下个月1号。即(获取2022-9,先会获取2022-10-1)
    // 2、然后在这个日期上加上day参数的整数值,再减去 1
    // new Date(2022,9,0) => 会先获取到2022-10-1加上我们定义的 0 ,再减去 1 ,即 2022-9-30,再通过getDate()方法获取到日期即可
    // console.log(new Date(2022, 9, 0))  =====>   Fri Sep 30 2022 00:00:00 GMT+0800 (中国标准时间)
};
// 获得每个月第一天星期几   0:星期日,1:星期一
const getFirstDay = (year: number, month: number) => {
    return new Date(year, month - 1, 1).getDay();
    // month - 1 是因为在new Date时 month 是从 0 开始的
};
//计算距离今天的后两天日期
const getTwoDay = (date: string) => {
    let result = new Date(new Date(date).getTime() + 2 * 24 * 60 * 60 * 1000);
    return result.getFullYear() + '-' + (result.getMonth() + 1) + '-' + result.getDate();
};
//计算距离今天的后六天日期
const getSixDay = (date: string) => {
    let result = new Date(new Date(date).getTime() + 6 * 24 * 60 * 60 * 1000);
    return result.getFullYear() + '-' + (result.getMonth() + 1) + '-' + result.getDate();
};
// 比较两个日期的大小
const dateCompare = (date1: string, date2: string) => {
    var str1 = [];
    var str2 = [];
    str1 = date1.split('-');
    str2 = date2.split('-');
    if (parseInt(str1[0]) == parseInt(str2[0]) && parseInt(str1[1]) == parseInt(str2[1]) && parseInt(str1[2]) == parseInt(str2[2])) {
        return 3;
    } else {
        if (parseInt(str1[0]) > parseInt(str2[0])) {
            return 1;
        } else if (parseInt(str1[0]) < parseInt(str2[0])) {
            return 0;
        } else {
        }
        if (parseInt(str1[1]) > parseInt(str2[1])) {
            return 1;
        } else if (parseInt(str1[1]) < parseInt(str2[1])) {
            return 0;
        } else {
        }
        if (parseInt(str1[2]) > parseInt(str2[2])) {
            return 1;
        } else if (parseInt(str1[2]) < parseInt(str2[2])) {
            return 0;
        } else {
        }
        return 0;
    }
};

let date = new Date();
year.value = date.getFullYear();
month.value = date.getMonth() + 1;
today.value = date.getDate();
startEnv.value = getTwoDay(year.value + '-' + month.value + '-' + today.value);
endEnv.value = getSixDay(year.value + '-' + month.value + '-' + today.value);

// 指定初始化日期的方法
const createCalendar = (year: number, month: number) => {
    // 清空数组
    // pickerDate = []; 此种方法数组会失去响应式
    pickerDate.splice(0, pickerDate.length);
    let picks: Array<Pinks> = [];
    let currentMonth: boolean = false;
    if (date.getFullYear() === year && date.getMonth() + 1 === month) {
        currentMonth = true;
    } else {
        currentMonth = false;
    }
    // 获取本月第一天是周几
    let monthStartDate = getFirstDay(year, month);
    // 获取上个月的最后一天
    let lastMonthRestDay = new Date(year, month - 1, 0).getDate();
    // 求上个月剩余多少天显示在本月
    for (let i = 0; i < monthStartDate; i++) {
        picks.push({
            dateNum: lastMonthRestDay, // 上月最后几天日期
            outfocus: true, // 表示这个日期已经过去了,字体渲染为灰色
        });
        lastMonthRestDay--;
    }
    picks = picks.reverse();
    //本月天数
    let indexMoth = getMonthLen(year, month);
    for (let i = 1; i <= indexMoth; i++) {
        let showday: boolean = false;
        if (currentMonth) {
            if (today.value === i) {
                showday = true;  // 默认选中当天
            } else {
                showday = false;
            }
        }
        if (currentMonth && today.value > i) {
            picks.push({
                dateNum: i,
                outfocus: true,
                showday: showday,
            });
        } else {
            picks.push({
                dateNum: i,
                outfocus: false,
                showday: showday,
            });
        }
    }
    let nextMonLen = 42 - picks.length;
    //下月天数显示在本月
    for (var i = 1; i <= nextMonLen; i++) {
        picks.push({
            dateNum: i,
            outfocus: true,
        });
    }
    // 这种方式也会失去响应式
    // pickerDate.push(...picks)
    // 总结:失去响应式的方法:解构赋值,等号赋值给数组。。。
    picks.forEach(item => {
        pickerDate.push(item);
    });
    console.log(picks);
};
// 初始化时间
createCalendar(year.value, month.value);
// 点击上月
const preMon = () => {
    // 选择日期从本月开始
    if (year.value == date.getFullYear() && month.value <= date.getMonth() + 1) {
        return;
    }
    month.value -= 1;
    if (month.value < 1) {
        year.value -= 1;
        month.value = 12;
    }
    // 重新调用渲染页面
    createCalendar(year.value, month.value);
};
// 点击下月
const nextMon = () => {
    month.value += 1;
    if (month.value > 12) {
        year.value = year.value + 1;
        month.value = 1;
    }
    createCalendar(year.value, month.value);
};

const checkDay = (dateNum: number, outfocus: boolean) => {
    if (!outfocus) {
        let check_day = year.value + '-' + month.value + '-' + dateNum;
        if (dateCompare(endEnv.value, check_day) == 0) {
            //开始后
            endEnv.value = check_day;
            showEndEnvfun(dateNum);
        } else if (dateCompare(endEnv.value, check_day) == 3) {
            //点结束当天
            startEnv.value = check_day;
            showHalffun(dateNum);
        } else if (dateCompare(startEnv.value, check_day) == 3) {
            //点开始当天
            endEnv.value = check_day;
            showHalffun(dateNum);
        } else if (dateCompare(startEnv.value, check_day) == 1) {
            startEnv.value = check_day;
            showStartEnvfun(dateNum);
        } else if (dateCompare(startEnv.value, check_day) == 0 && dateCompare(endEnv.value, check_day) == 1) {
            var disStartEnvLen = getDatePeriod(startEnv.value, check_day) - 1;
            var disSEndEnvLen = getDatePeriod(endEnv.value, check_day) - 1;
            if (disStartEnvLen > disSEndEnvLen) {
                endEnv.value = check_day;
                showEndEnvfun(dateNum);
            } else {
                startEnv.value = check_day;
                showStartEnvfun(dateNum);
            }
        }
    }
};
const showStartEnvfun = (dateNum: number, outfocus?: boolean) => {
    if (!outfocus) {
        if (startEnv.value == year.value + '-' + month.value + '-' + dateNum) {
            return true;
        } else {
            return false;
        }
    }
};
const showEndEnvfun = (dateNum: number, outfocus?: boolean) => {
    if (!outfocus) {
        if (endEnv.value == year.value + '-' + month.value + '-' + dateNum) {
            return true;
        } else {
            return false;
        }
    }
};
const showBlack = (dateNum: number, outfocus?: boolean) => {
    if (!outfocus) {
        if (dateCompare(startEnv.value, year.value + '-' + month.value + '-' + dateNum) == 0 && dateCompare(year.value + '-' + month.value + '-' + dateNum, endEnv.value) == 0) {
            return true;
        } else {
            return false;
        }
    }
};
const showHalffun = (dateNum: number, outfocus?: boolean) => {
    if (!outfocus) {
        if (startEnv.value == year.value + '-' + month.value + '-' + dateNum && endEnv.value == year.value + '-' + month.value + '-' + dateNum) {
            return true;
        } else {
            return false;
        }
    }
};
</script>

<style lang="less" scoped>
.date-picker {
    width: 210px;
    height: 230px;
    font-size: 14px;
    // background-color: red;
    border: 1px solid #ccc;
    margin: 100px auto;
    .date-picker-box {
        .date-picker-box-header {
            display: flex;
            justify-content: space-between;
            padding: 10px;
            border-bottom: 1px solid #ccc;
            .date-picker-box-header-prev,
            .date-picker-box-header-next {
                cursor: pointer;
                text-align: center;
            }
        }
        .date-picker-box-content {
            .date-picker-box-content-week {
                display: flex;
                align-items: center;
                width: 100%;
                .date-picker-box-content-weekday {
                    width: 30px;
                    text-align: center;
                }
            }
            .date-picker-box-content-cont {
                display: flex;
                flex-wrap: wrap;
                width: 100%;
                .date-picker-box-content-cont-day {
                    width: 30px;
                    text-align: center;
                }
                .start {
                    background: #5ec443;
                }
                .black {
                    background: #e2e2e2;
                }
                .end {
                    background: #d44040;
                }
                .outfocus {
                    color: #e3e3e3;
                }
            }
        }
        .date-picker-box-footer {
            display: flex;
            justify-content: space-between;
            padding: 5px 10px;
            border-top: 1px solid #ccc;
        }
        .confim {
            text-align: center;
            line-height: 20px;
            height: 20px;
        }
    }
}
</style>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
根据提供的引用内容,可以看出在Vue3+TS中使用el-date-picker组件来获取年月日的取值。在模板中,可以使用v-model指令将选择的日期绑定到相应的数据属性上。例如,可以使用value1、value2和value3来分别绑定年、月和日的取值。\[1\] 在方法中,可以使用getdatetime()方法来给value1、value2和value3赋值,将它们初始化为当前日期。\[3\] 另外,如果需要将时间控件的格式转换为特定的格式,可以使用format属性来指定日期的显示格式。例如,可以使用"yyyy年"来显示年份,"MM月"来显示月份,"dd日"来显示日期。\[1\] 如果需要获取完整的日期时间,可以使用type属性设置为"datetime",并使用value-format属性来指定日期时间的格式,例如"yyyy-MM-dd HH:mm"。\[2\] 总结起来,使用el-date-picker组件可以通过v-model指令和format属性来获取年月日的取值,使用type属性和value-format属性来获取完整的日期时间的取值。 #### 引用[.reference_title] - *1* *3* [vue-element日期选择器(默认显示当前年月日,并且只能选择当前及当前之前的日期)](https://blog.csdn.net/m0_50899555/article/details/122962517)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [el-date-picker时间插件获取值格式问题](https://blog.csdn.net/u014572906/article/details/108003894)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hoki802

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值