手写Vue日历组件
作者:互联网
1、创建myCalendar组件。
<template> <div class="myCalendar"> <div class="myCalendar_topBar"> <div class="topBar_left"> <span class="topBtn" @click="YearPrev"><<</span> <span class="topBtn" @click="MonthPrev"><</span> </div> <div class="topBar_center">{{currentYear}}-{{currentMonth<10?'0'+currentMonth:currentMonth}}</div> <div class="topBar_right"> <span class="topBtn" @click="ToDay">今天</span> <span class="topBtn" @click="MonthNext">></span> <span class="topBtn" @click="YearNext">>></span> </div> </div> <div class="myCalendar_container"> <table class="myCalendar_table"> <thead class="myCalendar_head"> <template v-for="(head,headIdx) in headList"> <th :key="headIdx">{{head}}</th> </template> </thead> <tbody class="myCalendar_body"> <tr v-for="row in Math.ceil(bodyList.length/7)"> <td class="item-date" v-for="(item) in bodyList.slice((row>0?(row-1):row)*7,(row)*7)"> <div v-if="item.day" class="date_container" @click="selectDate(item)" :class="{'active':item.day===currentDay}"> <slot name="dateCell" :data="item"> <span class="date">{{item.day}}</span> </slot> </div> </td> </tr> </tbody> </table> </div> </div> </template> <script> export default { name: "myCalendar", props:{ date:{},//可传入日期 }, data() { return { page: "myCalendar", headList:['日','一','二','三','四','五','六'], bodyList:[ // {date:'2021-05-01',forbidden:false} ], currentYear:"", currentMonth:"", currentDay:"", } }, mounted() { this.init(); }, methods: { init(date) { if(!date){ date = new Date(); if(this.date){ date = new Date(this.date); } } this.currentYear = date.getFullYear(); this.currentMonth = date.getMonth()+1; this.currentDay = date.getDate(); this.renderList(); }, YearPrev(){ this.currentYear--; this.currentDay = 1; this.renderList(); }, MonthPrev(){ this.currentMonth--; this.currentDay = 1; if(this.currentMonth===0){ this.currentYear--; this.currentMonth = 12; } this.renderList(); }, YearNext(){ this.currentYear++; this.currentDay = 1; this.renderList(); }, ToDay(){ this.init(new Date()) }, MonthNext(){ this.currentMonth++; if(this.currentMonth===13){ this.currentYear++; this.currentMonth = 1; } this.currentDay = 1; this.renderList(); }, renderList(){ let currentYear = parseFloat(this.currentYear); let currentMonth = parseFloat(this.currentMonth); let currentDay = parseFloat(this.currentDay); // console.log(currentDay) let firstDay = `${currentYear}-${currentMonth<10?'0'+currentMonth:currentMonth}-01`; let firstWeekDay = new Date(firstDay).getDay(); let nextYear,nextMonth; if(parseFloat(currentMonth) === 12){ nextYear = parseFloat(currentYear)+1; nextMonth = 1; }else{ nextYear = currentYear; nextMonth = parseFloat(currentMonth)+1; } let nextMonthFirstDay = `${nextYear}-${nextMonth<10?'0'+nextMonth:nextMonth}-01`; let lastDay = new Date(new Date(nextMonthFirstDay).getTime() - 24*60*60*1000).getDate(); // console.log(lastDay); // console.log(firstWeekDay); let bodyList = []; let cellLength = lastDay+firstWeekDay; while (cellLength%7!==0){ cellLength++; } for(let i = 1;i <= cellLength;i++){ let item = {date:'',year:currentYear,month:currentMonth,day:"",forbidden:false}; if(i > firstWeekDay){ if(i<=(lastDay+firstWeekDay)){ let itemDay = i - firstWeekDay; item.day = itemDay; item.date = `${currentYear}-${currentMonth<10?'0'+currentMonth:currentMonth}-${itemDay<10?'0'+itemDay:itemDay}`; }else{ item.forbidden = true; } }else{ item.forbidden = true; } bodyList.push(item); } this.bodyList = bodyList; let currentItem = this.bodyList.filter(val=>{ return val['day'] === currentDay; }); if(currentItem.length>0){ this.selectDate(currentItem[0]); } // console.log(JSON.parse(JSON.stringify(bodyList))) }, //选择日期回调函数 selectDate(item){ this.currentDay = parseFloat(item.day); this.$emit('selectDate',{cellInfo:item}); }, } } </script> <style lang="scss"> $defaultColor:#296BB5; .myCalendar{ position: relative; width: 100%; min-width: 250px; display: flex; flex-direction: column; // padding: 10px; .myCalendar_topBar{ position: relative; display: flex; justify-content: space-between; align-items: center; color: #fff; background-color: $defaultColor; height: 40px; .topBar_center{ position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); } .topBtn{ margin: 0 10px; cursor: pointer; } } .myCalendar_container{ background-color: #fff; padding: 0 20px; border: 1px solid #ddd; } .myCalendar_table{ border-collapse: collapse; width: 100%; margin-bottom: 10px; .myCalendar_head{ th{ height: 30px; line-height: 30px; } } .myCalendar_body{ border: 1px solid #ddd; } .item-date{ position: relative; border: 1px solid #ddd; padding-top: 14%; .date_container{ position: absolute; top:0; left: 0; width: 100%; height: 100%; cursor: pointer; overflow: hidden; .date{ // display: flex; // align-items: center; // justify-content: center; width: 100%; height: 100%; // text-align: center; } &.active{ color: #fff; background-color: $defaultColor; } } } } } </style>
2、使用时引入import myCalendar from "../common/myCalendar";
3、
<myCalendar :date="date" @selectDate="selectDate"> <template slot="dateCell" slot-scope="{data}">
<!-格式化显示数据背景等-> <div class="date"> {{data.day}} <div v-for="(item,index) in calendarList" :key="index"> <div v-if="(item.CF_FollowDate).indexOf(data.date)!=-1"> <div class="item" v-for="(item2,index2) in item.list" :key="index2" placement="right"> <div class="content">{{item2.label}}:{{item2.num}}</div> </div> </div> </div> </div> </template> </myCalendar>
标签:renderList,Vue,日历,currentYear,currentDay,date,手写,currentMonth,myCalendar 来源: https://www.cnblogs.com/xiongK/p/15330753.html