基于 vue 的日历

11 篇文章 0 订阅
本文介绍了一个使用 Vue.js 编写的日历组件,包括切换上/下个月的功能,以及根据当前日期填充日历。代码展示了如何处理日历布局,计算星期一和星期日的起始,并考虑了闰年的天数。尽管存在一些限制,如只能从周一开始展示日期,但该组件可以作为进一步开发的基础,以增加更多功能,如周视图、事件标记等。
摘要由CSDN通过智能技术生成

先上代码

template 部分

    <div class="card-wrap">
      <div 
      	class="header-line"  >
        <span 
        	@click="toPreMonth" 
        	title="上个月" 
        	style="cursor:pointer;padding:0 5px"
        >&lt;</span>
        <div 
        	class="center" 
        	style="width:calc(100% - 20px);text-align:center"
        >
          <span>{{currentYear}}年</span>
          <span>{{currentMonth}}月</span>
        </div>
        <span  
        	@click="toNextMonth" 
        	title="下个月"  
        	style="cursor:pointer;padding:0 5px"
        >&gt;</span>
      </div>
      <div 
      	class="day-content" 
      >
        <div 
        	class=" header" 
        	style="text-align:center;font-weight:bold;" 
        	v-for="(item,index) in ['Mon','Tue','Wed','Thu','Fri','Sta','Sun']" 			 		
        	:key="'day'+index"
        >{{item}}</div>
        <div 
        	class="day-item " 
        	:class="item.class" 
        	style="text-align:center;" 
        	v-for="(item,index) in dateList" 
        	:key="'date'+index"
        >{{item.date}}</div>
      </div>
    </div>	

js 部分

	// 上个月
	toPreMonth(){
      this.dateList = [];
      if(this.currentMonth > 1){
        this.currentMonth --;
      }else{
        this.currentMonth = 12;
        this.currentYear --;
      }
      this.getdateList();
    },
    // 下个月
    toNextMonth(){
      this.dateList = [];
      if(this.currentMonth < 12){
        this.currentMonth ++;
      }else{
        this.currentMonth = 1;
        this.currentYear ++;
      }
      this.getdateList();
    },
    // 组件初始化的时候,获取当前的时间(写在 mounted 或者 created 中)
    getCurrent(){
      let year = new Date().getFullYear();
      let month = new Date().getMonth()+1;
      this.currentYear = year;
      this.realCurrentYear = year;
      this.currentMonth = month;
      this.realCurrentMonth = month;
      this.getdateList();
    },
    // 根据传入的月份与年份,获取日历的展示列表(按照 6行 * 7列 处理的数据)
    getdateList(year, month){
      if(!year){
        year = this.currentYear;
        month = this.currentMonth;
      }
      year = this.currentYear, month = this.currentMonth;
      let firstDate = new Date(`${year}/${month}/1`);
      let monthDayNum = this.getMonthNum(year,month);
      let firstDay = new Date(`${year}/${month}/1`).getDay();
      firstDay = firstDay == 0 ? 7 : firstDay;

      // 减一是排除一号当天 (如果当月的一号不是星期一,则计算天数把上个月的挪几天过来,加在数组前面)
      for(let i = 1;i<=firstDay - 1;i++){
        let dateStr = new Date(firstDate.getTime() - i * 24 * 60 * 60 * 1000);
        let date = dateStr.getDate();
        this.dateList.unshift({date,dateStr,class:'gray',type:'pre-mon'})
      }
      // 放置现在的年月 (往数组中推入当月的日期)
      let finalDate = null;
      for(let i = 1;i <= monthDayNum;i++){
        let dateStr = new Date(`${year}/${month}/${i}`);
        let date = dateStr.getDate();
        // 打印时间
        // 关于判断当前日期是不是今天,还需要处理一下
        let className = dateStr.getTime() == new Date(`${this.realCurrentYear}/${this.realCurrentMonth}/1`) ? 'current' : '';
        this.dateList.push({date,dateStr,class:className})
        if(i == monthDayNum){
          finalDate = dateStr;
        }
      }
      // 放置末尾的几天 (看看离 6 * 7 行数据还差几天,从下个月去拿数据)
      let numMinus = Math.abs(this.dateList.length - 42);
      console.log(finalDate,'finalDate')
      for(let i = 1;i<= numMinus;i++){
        let dateStr = new Date(new Date(finalDate).getTime() + i * 24 * 60 * 60 * 1000);
        // 按照最后一天进行
        let date = dateStr.getDate();
        this.dateList.push({date,dateStr,class:'gray',type:'next-mon'})
      }
      console.log(this.dateList,'dateList')
    },
    // 获取月份对应的天数
    getMonthNum(year = 2020,month = 1) { 
      if(month < 1 || month > 12){
        console.log("参数不合法")
        return 
      }
      let num = 28;
      switch(month){
        case 1:
          num = 31;break;
        //计算闰年的方式
        case 2:
          if(year%4 == 0 ||  (year % 400 == 0 && year % 100 == 0)){
            num = 29
          }else{
            num = 28
          }  
        ;break;
        case 3:
          num = 31;break;
        case 4:
          num = 30;break;
        case 5:
          num = 31;break;
        case 6:
          num = 30;break;
        case 7:
          num = 31;break;
        case 8:
          num = 31;break;
        case 9:
          num = 30;break;
        case 10:
          num = 31;break;
        case 11:
          num = 30;break;
        case 12:
          num = 31;break;
        default:
          num = 28;break;
      }
      return num;//默认就是28
    },

样式

	.header-line {
		display:flex;
		justify-content:sapce-between;
		align-items:center;
		width:100%;
		padding:8px 0;
		border:1px solid red;
		box-sizing:border-box;
	}
	.day-content {
		display:grid;
		grid-template-columns:auto auto auto auto auto auto auto;
		grid-template-rows:75px 75px 75px 75px 75px 75px 75px;
		align-items:center;
		width:100%;
		border:1px solid #f0f;
		box-sizing:border-box;
	}

示意图

在这里插入图片描述

存在弊端

  1. 之前只是做做demo,想到就写了,写完之后发现没有保存当前的年月日【问题不大,再整一组变量在初始化的时候存起来就可了】
  2. 目前的日历是从周一开始展开日期,如果换成周日,需要一点改动,这部分还没有进行灵活处理
  3. 功能还比较单一(后面有兴趣再上来补充功能)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值