vue日历,可以按周、月切换

仿钉钉的日历,可以实现周、月切换,代码是在另一位大神那里参考修改的,感谢https://blog.csdn.net/x_xiaoqi/article/details/79142055#commentBox

废话不多说,上代码!

<template>
  <div class="calendarBox" style="overflow: hidden">
    <div class="date">
      <span @click="chooseTime" class="yearMonth left">{{now_year}}年{{now_month}}月 <span class="triangle-down"></span></span>
      <span @click="moveToday" class="right jin">今</span>
    </div>
    <div class="content" @touchstart="moveStart" @touchend="moveEnd">
      <div class="week">
        <ul>
          <li>日</li>
          <li>一</li>
          <li>二</li>
          <li>三</li>
          <li>四</li>
          <li>五</li>
          <li>六</li>
        </ul>
      </div>
      <div class="calendar">
          <ul id="d2">
            <li :class="{black:item.isNowMonth,gray:!item.isNowMonth,red:item.checked,today:item.old.isToday}" 
                v-for="(item,index) in list" @click="checkMe(item.id-1)" :key="index">
              <!-- <div style="font-size: 16px;height:.29rem;">{{item.num}}</div>
              <div style="font-size: 10px;height:.2rem;">{{item.old.old_str}}</div> -->
              <div class="date-day">
                <p style="font-size: 16px;font-weight:bold;height:.35rem;line-height:.35rem;">{{item.num}}</p>
                <p style="font-size: 10px;height:.2rem;line-height:.2rem;">{{item.old.old_str}}</p>
                <p style="height:.1rem;line-height:.1rem;"><span class="isEvent"></span></p>
              </div>
            </li>
          </ul>
      </div>
      <div class="text-center botop">
        <i class="icon iconfont" :class="mode=='M' ? 'icon-arrow-bottom' : 'icon-arrow-top' "></i>
      </div>
    </div>
  </div>
</template>
<script>
  import calendar from '../utils/calendar'
  export default{
    data() {
      return {
        selectTime:'',
        showPopup:false,
        list:[],  //日历显示的数据
        oneMonthList:[],  //暂存一个月的数据
        week:1,  //第几周
        check:'',
        moveStartX:'',  // 滑动开始的横坐标
        moveEndX:'',    // 滑动结束的横坐标
        moveStartY:'',  // 滑动开始的纵坐标
        moveEndY:'',    // 滑动结束的纵坐标
        now_year:'',  //当前年份
        now_month:'', //当前月份
        now_day:'', //当前日期
        mode:'M',  //当前是显示一个月还是一个星期(默认月)
        maxHeight:'4.5rem',
        minHeight:'.8rem',
        current_month:'',
      }
    },
    mounted() {
      let nstr=new Date() //当天时间
      this.now_year=nstr.getFullYear() //年份
      this.now_month=nstr.getMonth()+1 //月份
      this.current_month = nstr.getMonth()+1//当前月份
      this.now_day=nstr.getDate()  //日期
      this.createCalendar(this.now_year,this.now_month)
    },
    methods:{
      //      是否为闰年
      is_leap(year) {
        return (year%100==0?(year%400==0?1:0):(year%4==0?1:0));
      },
      //      选择日期
      checkMe(id){
        for(let i of this.oneMonthList){
          i.checked=false
        }
        //      不是本月的
        if(this.oneMonthList[id].isNowMonth==false && this.mode=='M'){
        //if(this.oneMonthList[id].isNowMonth==false){  这是原来代码,只判断是否时当前月
            let checkDay=this.oneMonthList[id].num
            //          上个月的
            if(this.oneMonthList[id].month=='last'){
              this.chooseMonth('pre')
              this.AddClass('leftmove')
              this.createCalendar(this.now_year,this.now_month)
              for( let s of this.oneMonthList){
                if(s.isNowMonth){
                  if(s.num==checkDay){
                    s.checked=true
                    this.now_day=s.num
                    this.check= s.id-1
                  }
                }
              }
//              下个月的
            }else if(this.oneMonthList[id].month=='next'){
              this.chooseMonth('next')
              this.AddClass('rightmove')
              this.createCalendar(this.now_year,this.now_month)
              for( let s of this.oneMonthList){
                if(s.isNowMonth==true){
                  if(s.num==checkDay){
                    this.now_day=s.num
                    s.checked=true
                    this.check= s.id-1
                  }
                }
              }
            }
        }else{
          this.oneMonthList[id].checked=true
          this.check=id
        }
        //        返回点击的时间
        let times=this.now_year+"-"+this.now_month+"-"+this.now_day
        this.$emit('checkTime',times)
      },
      //      创建一个月的日历
      createCalendar(year,month,day){
        console.log(year+'-'+month)
        this.list=[]
        let nstr1=new Date(year,month-1,1)  //当月第一天
        let firstDay=nstr1.getDay()   //当月第一天是星期几
        let m_days=[31,28+this.is_leap(year),31,30,31,30,31,31,30,31,30,31]; //各月份的总天数
        let lastMonth=''  //上个月
        let lastWeek=''   //上个月的最后一天的星期数
        let lastDays=''
        if(month==1){
          lastMonth=11
          lastWeek=new Date(year-1,lastMonth,m_days[lastMonth]).getDay()
          lastDays=m_days[lastMonth]-lastWeek
        }else{
          lastMonth=month-1
          lastWeek=new Date(year,lastMonth-1,m_days[lastMonth-1]).getDay()
          lastDays=m_days[lastMonth-1]-lastWeek
        }
        let list=[]
        let s=1
        let id=1
        for(let i=0;i<6;i++){
          for(let j=0;j<7;j++){
            let idx=i*7+j; //单元格自然序列号
            let  date_str=idx-firstDay+1; //计算日期
          //前一个月的最后几天
            if(date_str<=0){
            //月份在1到12之间
              if(month>1&&month<=12){
                this.list.push({id:id++,num:lastDays++,isNowMonth:false,month:'last',old:calendar.solar2lunar(year,month-1,lastDays-1),checked:false})
                //月份为1
              }else if(month==1){
                this.list.push({id:id++,num:lastDays++,isNowMonth:false,month:'last',old:calendar.solar2lunar(year-1,12,lastDays-1),checked:false})
              }
              //下一个月的开始几天
            }else if(date_str>m_days[lastMonth]){
              //月份在1到12之间
              if(month<12&&month>=1){
                this.list.push({id:id++,num:s++,isNowMonth:false,month:'next',old:calendar.solar2lunar(year,month+1,s-1),checked:false})
                //月份为12
              }else if(month==12){
                this.list.push({id:id++,num:s++,isNowMonth:false,month:'next',old:calendar.solar2lunar(year+1,1,s-1),checked:false})
              }
              //当前月份
            }else{
                this.list.push({id:id++,num:date_str,isNowMonth:true,month:'now',old:calendar.solar2lunar(year,month,date_str),checked:false})
            }
          }
        }
        this.oneMonthList=this.list
      },
      moveStart(e){
        this.moveStartX= e.changedTouches[0].clientX
        this.moveStartY= e.changedTouches[0].clientY
      },

      //通过选中的索引获取所在周数
      getWeekByCheck(check){
        var week = 1
        if(check<=6){
            week=1
        }else if(check>6&&check<=13){
            week=2
        }else if(check>6&&check<=20){
            week=3
        }else if(check>6&&check<=27){
            week=4
        }else if(check>6&&check<=34){
            week=5
        }else if(check>6&&check<=41){
            week=6
        }
        return week;
      },
      moveEnd(e){
        let self=this
        this.moveEndX= e.changedTouches[0].clientX
        this.moveEndY= e.changedTouches[0].clientY
        //  下拉
        if(this.moveEndY - this.moveStartY>40){
          this.mode='M'
          document.getElementById("d2").classList.remove("is-week")
          //$('#d2').css('height',this.maxHeight)
          document.getElementById('d2').setAttribute('style', 'height: '+this.maxHeight);
          this.createCalendar(this.now_year,this.now_month)
          if(this.check!=''){
            this.list[this.check].checked=true
          }
        }
        //   上拉
        if(this.moveStartY - this.moveEndY>40){
          this.mode='W'
          //$('#d2').css('height',this.minHeight)
          document.getElementById('d2').setAttribute('style', 'height: '+this.minHeight);
          document.getElementById("d2").classList.add("is-week");
          this.createdWeek(this.now_year,this.now_month)
          if(this.now_month==this.current_month){
              if(this.check!=''){
                this.list[this.check].checked=true
                this.week = this.getWeekByCheck(this.check)
              }else{
                //这里目的是,上拉的时候如果没有选择日期,那么就选中当前日期所在的周显示
                this.list.forEach((item,index)=>{
                  if(item.old.isToday){
                    this.week = this.getWeekByCheck(index)
                  }
                })
              }
          }else{
            if(this.check!=''){
              this.list[this.check].checked=true
            }
            this.week = this.getWeekByCheck(this.check)
          }
          this.oneMonthList=this.list
          this.list=this.oneMonthList.slice(this.week*7-7,(this.week*7-7)+7)
        }
 
        //下个月
        if(this.moveStartX-this.moveEndX>60 && this.mode=='M'){
          //$("#d2").css('opacity',0)
          document.getElementById('d2').setAttribute('style', 'opacity: 0');
          this.check=''
          //   月份为12月
          this.chooseMonth('next')
          this.AddClass('rightmove')
          this.createCalendar(this.now_year,this.now_month)
        //          上个月
        }else if(this.moveEndX-this.moveStartX>60 && this.mode=='M'){
          //$("#d2").css('opacity',0)
          document.getElementById('d2').setAttribute('style', 'opacity: 0');
          this.check=''
          this.AddClass('leftmove')
          //          月份为1月
          this.chooseMonth('pre')
          this.createCalendar(this.now_year,this.now_month)
        }
        //  周显示 (下一周)
        if(this.moveStartX-this.moveEndX>60 && this.mode=='W'){
          //console.log(this.oneMonthList);
          //标记符,按周显示时,判断是否进入了下一个月
          var flag = false;

          for(let i of this.oneMonthList){
            i.checked=false
          }
          this.check=''
          if(this.week<5){
            this.week++;
            this.list=this.oneMonthList.slice(this.week*7-7,(this.week*7-7)+7)
          }else if(this.week==5){
            // 第六周里有下个月的1号或最后一个数这个月的最大日期
            for(let u=0;u<7;u++){
              if(this.oneMonthList.slice(28,35)[u].num==1||this.oneMonthList.slice(28,35)[6].num==[31,28+this.is_leap(this.now_year),31,30,31,30,31,31,30,31,30,31][this.now_month-1]){
                var flag = true
                this.week=1
                this.chooseMonth('next')
                this.createdWeek(this.now_year,this.now_month)
                this.oneMonthList=this.list
                this.list=this.oneMonthList.slice(this.week*7-7,(this.week*7-7)+7)
                break;
              }
            }
            if(flag==false){
              this.week++;
            }
          }else if(this.week==6){
            for(let u=0;u<7;u++){
              if(this.oneMonthList.slice(36)[u].num==1||this.oneMonthList.slice(36)[u].num==[31,28+this.is_leap(this.now_year),31,30,31,30,31,31,30,31,30,31][this.now_month-1]){
                this.week=1
                this.chooseMonth('next')
                this.createdWeek(this.now_year,this.now_month)
                this.oneMonthList=this.list
                this.list=this.oneMonthList.slice(this.week*7-7,(this.week*7-7)+7)
                break;
              }
            }
            // this.week=1
            // this.chooseMonth('next')
            // this.createdWeek(this.now_year,this.now_month,1)
            // this.oneMonthList=this.list
            // this.list=this.oneMonthList.slice(this.week*7-7,(this.week*7-7)+7)
          }
          //console.log(this.list)
          //   月份为12月
          this.AddClass('rightmove')
          // 上一周
        }else if(this.moveEndX-this.moveStartX>60 && this.mode=='W'){
          for(let i of this.oneMonthList){
            i.checked=false
          }
          this.check=''
          this.AddClass('leftmove')
          //          月份为1月
          if(this.week>1){
            this.week--;
          }else if(this.week==1){
            this.week=6
            this.chooseMonth('pre')
            this.createdWeek(this.now_year,this.now_month)
            this.oneMonthList=this.list
          //   第六周里没有这个月的最大日期
            for(let u=0;u<7;u++) {
              if (this.oneMonthList.slice(35,42)[u].num != [31, 28 + this.is_leap(this.now_year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][this.now_month - 1]) {
                this.week = 5
                this.list = this.oneMonthList.slice(this.week * 7 - 7, (this.week * 7 - 7) + 7)
              }
            }
          }
          this.list=this.oneMonthList.slice(this.week*7-7,(this.week*7-7)+7)
        }
      },
      createdWeek(y,m){
        this.createCalendar(y,m)
      },
//      月份判断
      chooseMonth(time){
        if(time=='next'){
          if(this.now_month==12){
            this.now_month=1
            this.now_year=this.now_year+1
          }else{
            this.now_month=this.now_month+1
          }
        }else if(time=='pre'){
          if(this.now_month==1){
            this.now_month=12
            this.now_year=this.now_year-1
          }else{
            this.now_month=this.now_month-1
          }
        }
      },
//      添加类
      AddClass(classname){
        //$("#d2").removeClass('leftmove')
        //$("#d2").removeClass('rightmove')
        document.getElementById("d2").classList.add("leftmove");
        document.getElementById("d2").classList.add("rightmove");
        setTimeout(function () {
          //$("#d2").addClass(classname)
          document.getElementById("d2").classList.add(classname);
        },50)
      },
//      点击‘今’
      moveToday(){
        let today=new Date()
        this.now_year=today.getFullYear() //年份
        this.now_month=today.getMonth()+1 //月份
        this.now_day=today.getDate()  //日期
        this.createCalendar(this.now_year,this.now_month)
      },
//      选择时间
      chooseTime(){
        this.showPopup=true
      },
//      确定时间
      sure(){
        this.showPopup=false
        let time=this.selectTime.split('-')
        this.now_year=time[0]
        this.now_month=parseInt(time[1])
        this.now_day=parseInt(time[2])
        if(this.mode=='M'){
          this.createCalendar(this.now_year,this.now_month)
          for( let s of this.oneMonthList){
            if(s.isNowMonth){
              if(s.num==this.now_day){
                s.checked=true
                this.check= s.id-1
              }
            }
          }
        }else if(this.mode=='W'){
          this.createCalendar(this.now_year,this.now_month)
          let day=this.now_day
          let weeks=''
          for(let i=0;i<this.oneMonthList.length;i++){
            this.oneMonthList[i].checked=false
            if(this.oneMonthList[i].isNowMonth){
              if(day==this.oneMonthList[i].num){
                weeks=this.oneMonthList[i].id
              }
            }
          }
          if(weeks<=7){
            this.week=1
          }else if(weeks>7&&weeks<=14){
            this.week=2
          }else if(weeks>14&&weeks<=21){
            this.week=3
          }else if(weeks>21&&weeks<=28){
            this.week=4
          }else if(weeks>28&&weeks<=35){
            this.week=5
          }else if(weeks>35&&weeks<=42){
            this.week=6
          }
          this.oneMonthList[weeks-1].checked=true
          this.check=weeks-1
          this.list = this.oneMonthList.slice(this.week * 7 - 7, (this.week * 7 - 7) + 7)
        }
      }
  },
    // components: {
    //   Popup,
    //   DatetimeView
    // }
  }
</script>
<style lang="scss">
.calendarBox{
  .date{
    width: 100%;
    height: .4rem;
    line-height: .4rem;
    background: #DA5751;
    color: #fff;
    padding: 0 3%;
    font-size:16px;
    box-sizing: border-box;
  }
  .date:after{
    display: block;
    content: '';
    clear: both;
  }
  .left{
    float: left;
    position: relative;
  }
  .triangle-down{
    position: absolute;
    right: -.2rem;
    top: .2rem;
    width: 0;
    height: 0;
    border: 6px solid transparent;
    border-top: 6px solid #fff;
  }
  .right{
    float: right;
  }
  .date span.jin{
    display: block;
    width: .2rem;
    height: .2rem;
    line-height: .2rem;
    border: 2px solid #fff;
    border-radius: 50%;
    text-align: center;
    margin-top: .08rem;
  }
  .date span.jin:active{
    border-color:rgba(255,255,255,0.6);
    color: rgba(255,255,255,0.6);
  }
  .yearMonth:active .triangle-down{
    border-top-color: rgba(255,255,255,0.6);
  }
  .content{
    //height:5.4rem;
    border:1px #000 solid;
  }
  .content .botop{
    height: .2rem;
    line-height: .2rem;
  }
  .week ul{
    transition: all 1s ease;
    width: 100%;
    padding: 0;
    margin: .1rem 0;
    display: flex;
    display: -webkit-flex;
    display: -ms-flexbox;
    flex-wrap: wrap;
    -webkit-flex-wrap: wrap;
    font-size:14px;
    height:.4rem;
    line-height: .4rem;
  }
  .week li{
    flex: 0;
    flex-grow: 0;
    flex-shrink: 0;
    flex-basis: 13.2%;
    text-align: center;
    border: 2px solid transparent;
  }
  .tables {
    font-size: .14rem;
    color: #666;
    display: flex;
    display: -webkit-flex;
    display: -ms-flexbox;
  }
  .calendar ul{
    width: 100%;
    padding: 0;
    margin: .1rem 0;
    height: auto;
    display: flex;
    display: -webkit-flex;
    display: -ms-flexbox;
    flex-wrap: wrap;
    -webkit-flex-wrap: wrap;
  }
  .calendar ul li{
    flex: 0;
    flex-grow: 0;
    flex-shrink: 0;
    flex-basis: 13.2%;
    text-align: center;
    height: .65rem;
    border-radius: .05rem;
    border:2px transparent solid;
    position: relative;
    & .date-day{
      height:100%;
      width:80%;
      margin:0 auto;
      border:1px transparent solid;
    }
  }
  .calendar li.today .date-day{
    color: red;
  }
  .calendar .date-day{
    & .isEvent{
      background: #cccccc;
      border-radius: 50%;
      width:3px;
      height: 3px;
      position:absolute;
      bottom:0px;
      left:48%;
    }
  }
  .calendar li.red .date-day{
    background: $primaryColor;
    color:#ffffff;
    border-radius: 5px;
    & .isEvent{
      background: #ffffff;
    }
  }
  
  #d2{
    height:4.5rem;
    transition: height .5s ease;
  }
  .black{
    color: #333;
  }
  .gray{
    color: #ccc;
  }
  .is-week .gray{
    color:#333!important
  }
  @keyframes moveRight {
    from{
      transform: translateX(100%);
      opacity: 0;
    }
    to{
      transform: translateX(0);
      opacity: 1;
    }
  }
  @keyframes moveLeft {
    from{
      transform: translateX(-100%);
      opacity: 0;
    }
    to{
      transform: translateX(0);
      opacity: 1;
    }
  }
 
  .rightmove{
    animation: moveRight 1s both;
    -moz-animation: moveRight 1s both; /* Firefox */
    -webkit-animation: moveRight 1s both;  /* Safari 和 Chrome */
    -o-animation: moveRight 1s both;
  }
  .leftmove{
    animation: moveLeft 1s both;
    -moz-animation: moveLeft 1s both;  /* Firefox */
    -webkit-animation: moveLeft 1s both; /* Safari 和 Chrome */
    -o-animation: moveLeft 1s both;
  }
 
  .close{
    float: left;
    padding: .1rem;
    color: #828282;
  }
  .sure{
    float: right;
    padding: .1rem;
    color:#FF9900;
  }
}
</style>

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值