自定义封装日历组件

自定义日历

工作需要,但现有框架封装的日历无法满足需求,又找不到更好的插件,所以准备自己封装一个。

效果图和说明

在这里插入图片描述
一个很简易版的demo日历,本文只提供最基本的功能代码,便于阅读二开。

新建calendar.vue文件

<template>
<div class="calendar">
    <!-- 年月 -->
    <div class="head">
      <div>
        <span @click="setYear(false)">&lt;&lt;</span>
        <span style="margin-left: 17px;" @click="setMonth(false)">&lt; </span>
      </div>
      <div> {{date.year}}{{date.month}}</div>
      <div>
        <span style="margin-right: 17px;" @click="setMonth(true)">&gt; </span>
        <span @click="setYear(true)">&gt;&gt;</span>
      </div>
    </div>
    <!-- 星期 -->
    <div class="weeks">
        <ul>
            <li v-for="(item,index) of weeks" :key="index">{{item}}</li>
        </ul>
    </div>
    <!---->
    <div class="days">
        <ul>
            <li v-for="(item,index) of days" :key="index" :class="{'ash':item.cls}">{{item.val}}</li>
        </ul>
    </div>
</div>
</template>

<script>
export default {
    data(){
      return{
          date:{
              year:'',
              month:''
          },
          weeks:['日', '一', '二', '三', '四', '五', '六'],
          days:[],
      }
    },
    methods:{
        // 获取年、月
        getDate(){
            let date = new Date()
            this.date.year = date.getFullYear()
            this.date.month = date.getMonth()+1
            this.getViewDays()
        },
        // 获取界面中显示的天
        getViewDays(){
            let oneDayWeek = new Date(`${this.date.year}-${this.date.month}-01`).getDay()
            let lastMonth = this.date.month-1 > 0 ? this.date.month-1 : 12
            // 获取上月天数
            let lastMonthDays = this.getDays(lastMonth)
            this.days = []
            // 补齐上月天数
            for(let i=0; i<oneDayWeek; i++){
                this.days.push({
                    val: lastMonthDays - oneDayWeek + i +1,
                    cls:true
                })
            }

            let thisMonthDays = this.getDays(this.date.month)
            // 放入这月天数
            for(let i=1; i<=thisMonthDays; i++){
                this.days.push({
                    val: i
                })
            }

            // 下月天数补齐
            let nextMonthDay = 42-this.days.length
            for(let i=1; i<=nextMonthDay; i++){
                this.days.push({
                    val: i,
                    cls:true
                })
            }
        },  
        // 年份更改
        setYear(state){
            if(state){
                this.date.year++
            }else{
                this.date.year--
            }
            this.getViewDays()
        },
        // 月份更改
        setMonth(state){
            if(state){
                if(this.date.month == 12){
                    this.date.year++
                    this.date.month = 1
                }else{
                    this.date.month++
                }
            }else{
                if(this.date.month == 1){
                    this.date.year--
                    this.date.month = 12
                }else{
                    this.date.month--
                }
            }
            this.getViewDays()
        },  
        // 获取一个月有多少天
        getDays(month){
            if([1,3,5,7,8,10,12].indexOf(month) != -1){
                return 31
            }else if([4,6,9,11].indexOf(month) != -1){
                return 30
            }else{
                if((this.date.year % 4 === 0 && this.date.year % 100 != 0) || this.date.year % 400 ==0){
                    return 29
                }else{
                    return 28
                }
            }
        }
    },
    mounted(){
        this.getDate()
    }
}
</script>

<style lang="scss" scoped>
.calendar{
    width: 380px;
    box-shadow: 0px 0px 3px #ccc;
    margin: 0 auto;
    margin-top: 30px;
    border-radius: 5px;
    padding: 15px 25px;
    .head{
        display: flex;
        justify-content: space-between;
        span{
            cursor: pointer;
        }
    }
    .weeks > ul{
        display: flex;
        justify-content: space-around;
        border-bottom: 1px solid #ccc;
        padding: 10px 0;
        font-size: 13px;
        margin-top: 20px;
    }
    .days > ul{
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        li{
            width: 54px;
            height: 40px;
            line-height: 40px;
            text-align: center;
        }
        .ash{
            color: #ccc;
        }
    }
}
</style>

最后保存运行即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值