在实现日历之前。我们需要对js中date对象的几个基本方法有所了解:

1 new Date().getDate ---》获取具体日期

2 new Date(year,month,date).getDay()-----》获取某年某月末某日是星期几(注意从0开始,0--》星期天,1星期一,依此内推)

3 new Date().getMonth()-----》获取当前的月份。注意月份是0-11. 0表示1月份,11表示12月份

先看一下基本效果:

 

首先我们看基本的结构

   <div id="wrap">
            <div class="head">
                <div class="left"><span class="prevY" @click="changeY('prev')">《</span><span class="prevM" @click.stop="changeM('prev')">◁</span></div>
                <div class="title">当前日期:{{fullDate}}</div>
                <div class="right"><span class="nextM" @click="changeM('next')">▷</span><span class="nextY" @click.stop="changeY('next')">》</span></div>
            </div>
            <div class="">
                <ul>
                    <li>日</li>
                    <li>一</li>
                    <li>二</li>
                    <li>三</li>
                    <li>四</li>
                    <li>五</li>
                    <li>六</li>
                </ul>
                <div class="list">
                    <template v-for="item in state.dataCount" :key="item">
                        <div class="block">
                            <div :class="isCurrentDate(item)?'active':'' "  v-if="isCurrentDate(item)">{{item}}</div>
                            <div  v-else>{{filteredDate(item)}} <span class="dot" v-if="isShowDot(item)"></span></div>
                        </div>
                    </template>
                </div>
            </div>
    </div>

我们最后的日期数据通过dataCount这个数组渲染出来,他是一个数字数组。

<script setup>
import { computed, onMounted, reactive, ref, toRaw, toRefs } from 'vue'

let state=reactive({
    dataCount:[],
    //得到当前日期
    curYear:0,
    curMonth:0,
    curDate:0,
    signInList:[
        {date:"2022-9-10"},
        {date:"2022-9-11"},
        {date:"2022-9-12"},
    ]
})


let currentYEAR=null
let currentMONTH=null

onMounted(()=>{
    let date=new Date()
    state.curYear=date.getFullYear()
    state.curMonth=date.getMonth()
    state.curDate=date.getDate()

    //初始化执行
    getDayCounts(state.curYear,state.curMonth)

    currentYEAR=toRaw( state.curYear)
    currentMONTH=toRaw( state.curMonth)
})

const fullDate= computed(()=>{
    return `${ state.curYear}-${state.curMonth+1}-${state.curDate}`
})


//获取当月总天数
const getDayCounts=()=>{

    let counts=new Date(state.curYear,state.curMonth+1,0).getDate()
    
    //获取当前第一天是星期几
    let firstWeekDay=new Date(state.curYear,state.curMonth,1).getDay()
    console.log("state--:",state)
    console.log("firstweekday:",firstWeekDay)
    for(let i=1;i<=counts+firstWeekDay;i++){
        let val=i-firstWeekDay;
        // if(val>0 && val<counts){
            state.dataCount.push(val)
        // }
    }
    let res= state.dataCount;
    console.log(res)
}

//更改年份
const changeY=(type)=>{
    state.dataCount=[];
    type=="prev"?state.curYear--:state.curYear++
   
    getDayCounts(state.curYear,state.curMonth)
}

//更改月份
const changeM=(type)=>{
 
    state.dataCount=[];
    if(type=="prev"){
        state.curMonth--;
        if(state.curMonth==0){
            state.curMonth=11;
            state.curYear--
        }
    }else{
        state.curMonth++;
        
        if(state.curMonth==11){
            state.curMonth=0;
            state.curYear++
        }
    }
    console.log("state.curYear,state.curMont",state.curYear,state.curMonth)
    getDayCounts(state.curYear,state.curMonth)
}

//判断是否是当前日期

const isCurrentDate=(date)=>{
    if(date> 0&& date<=state.dataCount.length){
        console.log("currentYEAR:",currentYEAR)
        if(date==state.curDate && currentYEAR==state.curYear && currentMONTH==state.curMonth){
                return true
        }

    }else{
        return false
    }
}


const filteredDate=(date)=>{
    return date>0?date:""
}

//签到处理
const isShowDot=(date)=>{
    let {curYear,curMonth,curDate}=toRefs(state)
    let itemDate=`${curYear.value}-${curMonth.value+1}-${date}`
    console.log("itemDate:",itemDate)
    let res=state.signInList.some(j=>j.date==itemDate)?true:false
    console.log("res:",res)
    return  res
}

这里有几个比较重要的函数:

1 getDayCounts--(获取总天数)

我们想得到当前月份的总天数,需要考虑到平年闰年等一些场景,所以我们通过设置下个月的最后日期为0,下个月的第0天实际上就是上个月的最后一天。而得到上个月的最后一天我们就能正确的得到当前这个月的最后一天。也就是做  let counts=new Date(state.curYear,state.curMonth+1,0).getDate() 这个设定。

2 我们要给当前日期做active样式。如何判断当前日期呢?当前日期是指当前年-月-日的日期。而每次我们切换年或者月的时候都是更改的全局下的state.curYear和state.curMonth,那它一定会改变。如何做一个固定值不是响应式的呢。这里我们对currentYEAR=toRaw( state.curYear)

currentMONTH=toRaw( state.curMonth)做了toRaw处理。

Logo

前往低代码交流专区

更多推荐