模拟一下日历

<template>

    <view class="calendar">

        <view class="top-bar">

            <u-icon name="arrow-left" class="top-change-month"  @click="turning('prev')"></u-icon>

            <view class="top-bar-ym">{{ y }}{{ text.year }}{{ m + 1 }}{{ text.month }}</view>

            <u-icon name="arrow-right" class="top-change-month"  @click="turning('next')"></u-icon>

        </view>

        <view class="week tHeader">

            <view class="week-day" v-for="(item, index) in weekDay" :key="index">{{ item }}</view>

        </view>


 

        <view class="week tbody" v-for="(item, index) in dates" :key="index+'y'">

            <view class="week-day" v-for="(item1, index1) in item" :key="index1">

                <view :class="['date_content', {'disabled':disabled, 'select_date':selectDate == item1.dates}]" v-if="item1.lm"

                @click="handlerClick(item1)">

                    <text class="date_a date_s" :class="item1.className ? item1.className : ''">{{ item1.date }}</text>

                </view>

            </view>

        </view>

       

        <image mode="scaleToFill" @click="trgWeek()" class="weektoggel"

            :class="{ down: !monthOpen }"></image>

    </view>

</template>

<script>

    export default {

        name: 'dncalendar',

        props: {

            // 第一列星期几

            weekstart: {

                type: Number,

                default: 1

            },

            // 只有迟到的日期

            lateddates: {

                type: Array,

                default: () => []

            },

            // 有旷课的日期

            truancyeddates: {

                type: Array,

                default: () => []

            },

            // 是否展开

            open: {

                type: Boolean,

                default: true

            },

            defaultDate: {

           

            },

            disabled: {

                type: Boolean,

                default: false

            }

        },

        data() {

            return {

                text: {

                    year: '年',

                    month: '月',

                    week: ['一', '二', '三', '四', '五', '六', '日'],

                    today: '今'

                },

                y: new Date().getFullYear(), // 年

                m: new Date().getMonth(), // 月

                dates: [], // 当前月日期集合

                positionTop: 0,

                monthOpen: true,

                choose: '',

                curDate: function() {

                    let date = new Date()

                    let str = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`

                    return new Date(str).getTime()

                }() ,

                // 设置选中日期高亮

                selectDate: '',

            }

        },

        created() {

            this.getdates(this.defaultDate)

        },

       

        onShow() {

            console.log("36988555")

           

        },

        computed: {

            // 顶部星期栏目

            weekDay() {

                return this.text.week.slice(this.weekstart - 1).concat(this.text.week.slice(0, this.weekstart - 1))

            },

            height() {

                return (this.dates.length / 7) * 80 + 'rpx'

            }

        },

        watch:{

            defaultDate(n) {

                this.getdates(n)

            }

        },

        methods: {

            getdates(n) {

                let date = n ? new Date(n) : new Date()

                let y = date.getFullYear()

                let m = date.getMonth()

                let d = date.getDate()

                this.dates = this.monthDay(y, m)

                this.choose = `${y}-${m + 1}-${d}`

                this.y = y;

                this.m = m;

            },

            // 获取当前月份天数

            monthDay(y, m) {

                let firstDayOfMonth = new Date(y, m, 1).getDay() // 当月第一天星期几

                let lastDateOfMonth = new Date(y, m + 1, 0).getDate() // 当月最后一天

                let lastDayOfLastMonth = new Date(y, m, 0).getDate() // 上一月的最后一天

                let dates = [] // 所有渲染日历

                let weekstart = this.weekstart == 7 ? 0 : this.weekstart // 方便进行日期计算,默认星期从0开始

                let startDay = (() => {

                    // 周初有几天是上个月的

                    if (firstDayOfMonth == weekstart) {

                        return 0

                    } else if (firstDayOfMonth > weekstart) {

                        return firstDayOfMonth - weekstart

                    } else {

                        return 7 - weekstart + firstDayOfMonth

                    }

                })()

                let endDay = 7 - ((startDay + lastDateOfMonth) % 7) // 结束还有几天是下个月的

                for (let i = 1; i <= startDay; i++) {

                    dates.push({

                        date: lastDayOfLastMonth - startDay + i,

                        day: weekstart + i - 1 || 7,

                        month: m - 1 >= 0 ? m - 1 : 12,

                        year: m - 1 >= 0 ? y : y - 1

                    })

                }

                for (let j = 1; j <= lastDateOfMonth; j++) {

                    let cur = new Date(`${y}-${m + 1}-${j}`).getTime();

                    dates.push({

                        date: j,

                        day: (j % 7) + firstDayOfMonth - 1 || 7,

                        month: m,

                        dates: `${y}-${(m + 1)>=10 ? m+1 : "0"+ (m + 1)}-${ j>= 10 ? j : "0"+ j}`,

                        year: y,

                        lm: true,

                        className: cur > this.curDate

                                ? "next"

                                : cur == this.curDate

                                ? 'cur'

                                : 'pre'

                    })

                }

                for (let k = 1; k <= endDay; k++) {

                    dates.push({

                        date: k,

                        day: (lastDateOfMonth + startDay + weekstart + k - 1) % 7 || 7,

                        month: m + 1 <= 11 ? m + 1 : 0,

                        year: m + 1 <= 11 ? y : y + 1

                    })

                }

               

                let arr2=[];

                let n = dates.length / 7;

                for(let i=0; i<n; i++) {

                    let arr = dates.slice(i*7,(i+1)*7)

                    arr2.push(arr)

                }

           

                return arr2

            },

       

           

            isToday(y, m, d) {

                let date = new Date()

                return y == date.getFullYear() && m == date.getMonth() && d == date.getDate()

            },

            // 切换成周模式

            trgWeek() {

                this.monthOpen = !this.monthOpen

                if (this.monthOpen) {

                    this.positionTop = 0

                } else {

                    let index = -1

                    this.dates.forEach((i, x) => {

                        this.isToday(i.year, i.month, i.date) && (index = x)

                    })

                    this.positionTop = -((Math.ceil((index + 1) / 7) || 1) - 1) * 80

                }

            },

            // 点击回调

            selectOne(i, event) {

                let date = `${i.year}-${i.month + 1}-${i.date}`

                if (i.month != this.m) {

                    console.log('不在可选范围内')

                    return false

                }

                this.choose = date

                this.$emit('on-click', date)

            },

           

            handlerClick(item) {

                let {dates} = item;

                this.selectDate = dates

                this.$emit('selectDate', dates)

            },

            // 上个月,下个月

            turning(_action) {

                if (_action === 'next') {

                    if (this.m + 1 == 12) {

                        this.m = 0

                        this.y = this.y + 1

                    } else {

                        this.m = this.m + 1

                    }

                } else {

                    if (this.m + 1 == 1) {

                        this.m = 11

                        this.y = this.y - 1

                    } else {

                        this.m = this.m - 1

                    }

                }

                this.dates = this.monthDay(this.y, this.m)

            }

        }

    }

</script>

<style lang="scss" scoped>

    .calendar {

       

        font-size: 28rpx;

        text-align: center;

        padding-bottom: 10rpx;

        .top-bar {

            display: flex;

            height: 80rpx;

            justify-content: center;

            .top-bar-ym{

                font-size: 32rpx;

                height: 80rpx;

                line-height: 80rpx;

            }

            .top-change-month{

                height: 80rpx;

                // width: 80rpx;

            }

        }

        .week {

            display: flex;

            // align-items: center;

            // height: 80rpx;

            // line-height: 80rpx;

            view {

                flex: 1;

            }

            .week-day{

                font-size: 24rpx;

                color: #0d0d0e;

                .date_content {

                    display: flex;

                    flex-direction: column;

                    justify-content: space-between;

                    align-items: center;

                    height: 100%;

                    background: #fff;

                    border-radius: 12rpx;

                    padding: 12rpx 0 12rpx 0;

                    box-sizing: border-box;

                    &:hover {

                        background: blue;

                        color: #fff;

                    }

                    &.disabled:hover {

                        background: #fff;

                        color: #000

                    }

                    &.select_date {

                        background: blue;

                        color: #fff;

                    }

                    .date_a{

                        height: 50rpx;

                        width: 50rpx;

                        border-radius: 50%;

                        // background: blue;

                        &.pre {

                            background: #D2DFFA;

                        }

                        &.cur {

                            background: #0C3391;

                            color: #fff;

                        }

                    }

                    .date_s {

                        display: flex;

                            justify-content: center;

                            align-items: center;

                    }

                    .date_b_c{

                    }

                }

            }

        }

        .content {

            position: relative;

            overflow: hidden;

            transition: height 0.4s ease;

            .days {

                transition: top 0.3s;

                display: flex;

                align-items: center;

                flex-wrap: wrap;

                position: relative;

                .item {

                    position: relative;

                    display: block;

                    height: 80rpx;

                    line-height: 80rpx;

                    width: calc(100% / 7);

                    .day {

                        font-style: normal;

                        display: inline-block;

                        vertical-align: middle;

                        width: 60rpx;

                        height: 60rpx;

                        line-height: 60rpx;

                        overflow: hidden;

                        border-radius: 14rpx;

                        .date_a {

                            position: absolute;

                            top: -16rpx;

                            left: 0;

                        }

                        .date_b {

                            position: absolute;

                            font-size: 12rpx;

                            left: -2rpx;

                        }

                        &.choose {

                            background-color: #3DB7BA;

                            color: #FFFFFF;

                        }

                        &.nolm {

                            color: #fff;

                            opacity: 0.3;

                        }

                    }

                    .late {

                        bottom: 0;

                        left: 50%;

                        font-style: normal;

                        width: 12rpx;

                        height: 12rpx;

                        background: #F7B300;

                        border-radius: 6rpx;

                        position: absolute;

                        margin-left: -6rpx;

                        pointer-events: none;

                    }

                    .truancy {

                        bottom: 0;

                        left: 50%;

                        font-style: normal;

                        width: 12rpx;

                        height: 12rpx;

                        background: #FF2222;

                        border-radius: 6rpx;

                        position: absolute;

                        margin-left: -6rpx;

                        pointer-events: none;

                    }

                    .today-text {

                        position: absolute;

                        font-size: 20rpx;

                        font-weight: normal;

                        width: 20rpx;

                        height: 20rpx;

                        line-height: 20rpx;

                        right: 0;

                        top: 10rpx;

                        color: #fff;

                    }

                }

            }

        }

        .hide {

            height: 80rpx !important;

        }

        .weektoggel {

            width: 80rpx;

            height: 40rpx;

            margin: 10rpx auto 0;

            &.down {

                transform: rotate(180deg);

            }

        }

    }

</style>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值