首页 > 建站教程 > 前端框架 >  基于vue的简单js日历代码正文

基于vue的简单js日历代码



    之前,我爱模板网写了一个js+dom的日历教程。最近在做一个基于element ui的项目,需要用到日历,但是需要深度定制。比如显示工作计划等。element-ui自带的日历放在node modules里面,不好修改。还不如自己写一个。
    于是,我就将之前的那个js+dom的日历拿过来,基于vue进行了改造,增加了开始日期和结束日期。这样的话,无论怎么改,都得心印手了。下面是代码:
css代码:
html,body,h1,h2,h3,h4,h5,h6,hr,p,iframe,dl,dt,dd,ul,ol,li,pre,form,button,input,textarea,th,td,fieldset{margin:0; padding:0;}
button{border: 0 none; background-color: rgba(0,0,0,0); cursor: pointer;}
html,body{font-size:14px; color:#000; font-family:'微软雅黑'}
img{border:none;}
ul,ol,dl{list-style-type:none}
/*浮动*/
.fl{float:left;}
.fr{float:right;}
/*清除浮动*/
.clear{clear:both;}
.clearfix{*zoom:1;}
.clearfix:before,.clearfix:after{display:table; clear:both; line-height:0; content:"";}

.flex{display:flex;}
.flex-start{justify-content:flex-start;}
.flex-end{justify-content:flex-end;}
.flex-between{justify-content:space-between;}
.flex-around{justify-content: space-around;}
.flex-center{justify-content:center;}
.flex-top{align-items: flex-start;}
.flex-middle{align-items:center;}
.flex-bottom{align-items: flex-end;}
.flex-grow-1{flex-grow: 1}
.flex-shrink-0{flex-shrink: 0}
.flex-wrap{flex-wrap:wrap;}

.calendar .calendar-top{padding:12px 20px; border-bottom: 1px solid #ebeef5;}
.calendar .next-prev{overflow: hidden;}
.calendar .next-prev button{font-size: 12px; padding: 7px 15px; color: #606266; border: 1px solid #dcdfe6; transition: all .2s ease;}
.calendar .next-prev button:first-child{border-right:0 none; border-radius: 3px 0 0 3px;}
.calendar .next-prev button:last-child{border-radius: 0 3px 3px 0;}
.calendar .next-prev button:hover{color: #409eff; border-color: #c6e2ff; background-color: #ecf5ff;}

.calendar .calendar-body{padding: 12px 20px 35px;}

.calendar .calendar-table{width:100%}
.calendar .calendar-table th{padding: 12px 0; color: #606266; font-weight: 400;}
.calendar .calendar-table tr:first-child td {border-top: 1px solid #ebeef5;}
.calendar .calendar-table td:first-child {border-left: 1px solid #ebeef5;}
.calendar .calendar-table td{border-bottom: 1px solid #ebeef5; border-right: 1px solid #ebeef5; vertical-align: top; transition: background-color .2s ease;}
.calendar .calendar-table td:hover{background-color: #f2f8fe; cursor: pointer;}
.calendar .calendar-table td .inner-calendar-day {box-sizing: border-box; padding: 8px; height: 85px;}
.calendar .calendar-table td .today{background-color: #fb0; color: #fff; font-weight: bold;}
html代码:
<div id="rootVue" style="width:800px; margin: 100px auto; padding: 25px">
    <div class="calendar">
        <div class="calendar-top flex flex-middle flex-between">
            <div class="start-end">
                {{calendarRange[0]}} 至 {{calendarRange[1]}}
            </div>
            <div class="next-prev flex flex-middle">
                <button @click="prevMonth">上个月</button>
                <button @click="nextMonth">下个月</button>
            </div>
        </div>
        <div id="calendar" class="calendar-body">
            <table class="calendar-table" cellpadding="0" cellspacing="0">
                <tr class="calendar-day"><th>日</th><th>一</th><th>二</th><th>三</th><th>四</th><th>五</th><th>六</th></tr>
                <tbody>
                    <tr class="calendar-day" v-for="(item,index) in calendarRenderData" :key="index">
                        <td v-for="(item2,index2) in item" :key="index2">
                            <div :class="['inner-calendar-day',item2.isToday ? 'today' : '']"v-html="item2.innerText"></div>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>
<!--这里先引入vue,到时候会作为组件整合进element-ui-->
<script src="js/vue.js"></script>
js代码:
new Vue({
    el: '#rootVue',
    data: {
        calendarRange: ['2020-07-01','2021-01-31'],
        startDate:'',
        endDate:'',
        curDate:'',
        calendarRenderData:[],
    },
    created(){
        this.startDate = this.calendarRange[0];
        this.endDate = this.calendarRange[1];
        this.curDate = this.calendarRange[0];
        this.renderCalendar();
    },
    watch:{
    },
    methods:{
        renderCalendar(){
            const curDate = new Date(this.curDate);
            const curYY = curDate.getFullYear(); //年份
            const curMM = curDate.getMonth(); //月份,不用来显示,不要+1
            const n1str = new Date(curYY,curMM,1); //当月第一天Date
            const todayDate = new Date();
            const todayDD = todayDate.getDate(); //今日日期
            const todayMM = todayDate.getMonth(); //今日月份 为了和mm进行比较,不要+1
            const todayYY = todayDate.getFullYear(); //今日年份
            const firstday = n1str.getDay(); //当月第一天星期几
            const m_days = new Array(31,28+this.is_leap(curYY),31,30,31,30,31,31,30,31,30,31); //各月份的总天数
            const tr_str = Math.ceil((m_days[curMM] + firstday)/7); //表格所需要行数
            let temp = [];
            for(i = 0;i < tr_str;i++) { //表格的行
                let trs = [];
                for(k = 0;k < 7;k++) { //表格每行的单元格
                    let td = {};
                    idx = i * 7 + k; //单元格自然序列号
                    date_str = idx - firstday + 1; //计算日期
                    if(date_str <= 0 || date_str > m_days[curMM]){
                        td.innerText = '&nbsp;';
                    }else{
                        td.innerText = curYY + '-' + this.zero(curMM + 1) + '-' + this.zero(idx - firstday + 1);
                    }
                    //标记今天
                    td.isToday = date_str === todayDD && curYY === todayYY && curMM === todayMM;
                    trs.push(td);
                }
                temp.push(trs);
            }
            this.calendarRenderData = temp;
        },
        prevMonth(){
            let curDate = new Date(this.curDate);
            curDate.setMonth(curDate.getMonth() - 1);
            if(curDate.getTime() < new Date(this.startDate).getTime()){
                alert('超出范围了');
                return;
            }
            this.curDate = this.formateDate(curDate);
            this.renderCalendar();
        },
        nextMonth(){
            let curDate = new Date(this.curDate);
            curDate.setMonth(curDate.getMonth() + 1);
            if(curDate.getTime() > new Date(this.endDate).getTime()){
                alert('超出范围了');
                return;
            }
            this.curDate = this.formateDate(curDate);
            this.renderCalendar();
        },
        formateDate(dd){
            return dd.getFullYear() + '-' + this.zero(dd.getMonth()+1) + '-' + this.zero(dd.getDate());
        },
        is_leap(year) {
           return (year%100==0?res=(year%400==0?1:0):res=(year%4==0?1:0));
        },
        zero(n){
            if(n<10){
                return '0'+n;
            }else{
                return n;
            }
        }
    },
    mounted(){
    }
});