学习笔记Vue(十 四)—— 用vue写一个日历组件

先看一下实现的效果:
在这里插入图片描述
实现日历的逻辑:

  1. 先写出日历的大致结构,分两个部分,头部和主体部分,日历先显示6排7列,总共42个数字,按从1到42来显示:
<div class="every-day" v-for="item in 42" :key="item"></div>

像这样:
在这里插入图片描述
然后获取当前日期是星期几,用日历中的数字减去这个数字,就使得1号在正确的位置上显示了。
获取当前日期是星期几的方法:

new Date(this.year, this.month - 1, 1).getDay(); //获取当前日期是星期几

然后再判断经过计算的日期,如果小于等于0,则应显示上个月被排版到这个月的日期,如果大于0且大于当前月份的总天数的话,则是下个月被排版到这个月的日期,也就是日历上的灰体字。
上个月日期显示:当前item 减去这个月1号的星期数,再加上上个月的总天数

<div class="other-day" v-else-if="item - beginDay <= 0">
{{item - beginDay + prevDays}}
</div>

下个月日期显示:当前item 减去这个月1号的星期数,再减去当前月的总天数

<div class="other-day" v-else>{{item - beginDay - curDays}}</div>

写不动了,直接上带注释的代码吧…

全部代码!
<template>
    <div class="calender">
        <div class="dateHeader">
            <div class="prev-month" @click="handlePrev"></div>
            <div class="show-date">{{year}}{{month}}{{day}}</div>
            <div class="next-month" @click="handleNext"></div>
        </div>
        <div class="dateContent">
            <div class="week-header">
                <div v-for="item in ['日','一','二','三','四','五','六']" :key="item">
                    {{item}}
                </div>
            </div>
            <div class="week-day">
                <div class="every-day" v-for="item in 42" :key="item">
                    {{item}}
                    <div v-if="item - beginDay > 0 && item - beginDay <= curDays"
                        :class="{'now-day': `${year}-${month}-${item-beginDay}` === curDate,
                                 'active-day':  `${year}-${month}-${item-beginDay}` === `${year}-${month}-${day}`}"
                        :data-day="item - beginDay"  
                        @click="handleChooseDay">
                        {{item - beginDay}}
                    </div>
                    <div class="other-day" v-else-if="item - beginDay <= 0">{{item - beginDay + prevDays}}</div>
                    <div class="other-day" v-else>{{item - beginDay - curDays}}</div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data () {
            return {
                year: null,
                month: null,
                day: null,
                curDate: ''
            }
        },
        created(){
            this.getInitTime();
            // console.log(new Date(this.year, this.month - 1, 1).getDay());
        },
        methods: {
            getInitTime () {
                //初始化,获取当前年月日
                const date = new Date();
                this.year = date.getFullYear();
                this.month = date.getMonth() + 1;
                this.day = date.getDate();
                this.curDate = `${this.year}-${this.month}-${this.day}`;
            },
            handleChooseDay(e){
                //获取点击选中的日期   :data-day
                console.log(e.target.dataset); // DOMStringMap {day: "11"}
                this.day = e.target.dataset.day;
            },
            handlePrev(){
                //点击上个月,如果是1月,则上个月是12月,年份减1
                if(this.month == 1){
                    this.month = 12;
                    this.year -- ;
                }else{
                    this.month --;
                }
                this.computedDay();
            },
            handleNext(){
                //点击下个月  如果是12月,下个月则变成1月,年份加一
                if(this.month == 12){
                    this.month = 1;
                    this.year ++;
                }else{
                    this.month ++;
                }
                this.computedDay();
            },
            computedDay(){
                //如果选中的是一个月里的最后一天,比如31,下一个月只有30天,反到下一个月要自动选中30
                const allDay = new Date(this.year, this.month, 0).getDate();
                if(this.day > allDay){
                    this.day = allDay;
                }
            }
        },
        computed: {
            beginDay() {
                //这个月的1号是星期几
                return new Date(this.year, this.month - 1, 1).getDay();
            },
            curDays() {
                //直接拿到这个月的天数
                return new Date(this.year, this.month, 0).getDate();
            },
            prevDays(){
                //上个月的天数
                return new Date(this.year, this.month-1, 0).getDate();
            }
        }
    }
</script>

<style>
    .calender{
        width: 560px;
        /* height: 500px; */
    }
    .dateHeader {
        margin-bottom: 10px;
    }
    .dateHeader div{
        display: inline-block;
    }
    .prev-month{
        width: 0; 
        height: 0;
        border-width: 15px;
        border-style: solid;
        border-color:transparent #f44444 transparent transparent;
    }
    .show-date{
        width: 87%;
        text-align: center;
        height: 30px;
        line-height: 30px;
        vertical-align: top;
    }
    .next-month{
        width: 0; 
        height: 0;
        border-width: 15px;
        border-style: solid;
        border-color:transparent transparent transparent #f44444;
    }
    .week-header{
        background: #f44444;
    }
    .week-header div{
        display: inline-block;
        width: 70px;
        height: 35px;
        line-height: 35px;
        text-align: center;
        color: #fff;
        margin-left: 5px;
        margin-right: 5px;
    }
    .week-day div{
        width:70px;
        height: 45px;
        line-height: 45px;
        margin: 5px;
        text-align: center;
        display: inline-block;
        cursor: pointer;
    }

    .other-day {
        color: #999;
    }
    .now-day{
        color: #fff;
        background: #f44444;
    }
    .active-day{
        border: 2px solid #f44444;
    }
</style>

(完)

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值