废话不多说先上效果图:
点击头部年月部分可以选择日期。左右按钮可以切换月份。(蓝色标记为特定需要处理的日期)
DateTools.vue 代码部分:
<template> <div class="date-tools"> <div class="date-years"> <button class="date-btn date-left" @click="subMonth()"><</button> <button class="date-middle" @click="selectYM()">{{panelYear}}年{{panelMonth+1}}月</button> <button class="date-btn date-right" @click="addMonth()">></button> </div> <div class="date-weeks"> <span>日</span> <span>一</span> <span>二</span> <span>三</span> <span>四</span> <span>五</span> <span>六</span> </div> <div class="date-days"> <template v-for="(day,index) in dayFullList"> <button v-if="day!=0"> <a href="javascript:void(0);" v-if="(trainDateFullList.includes(day))" class="active" @click="getCurrentDay(day)">{{day | filterDay}} </a> <a href="javascript:void(0);" v-else>{{day | filterDay}} </a> </button> <button v-else> <a href="javascript:void(0);" style="opacity:0;">{{day}} </a> </button> </template> </div> <!-- 年月下拉框 --> <div class="drop-down-ym" v-if="showDropDownYM"> <div class="drop-down-y"> <a href="javascript:void(0);" v-for="(item,index) in yearList" @click="selectY(item)">{{item}}</a> </div> <div class="drop-down-m"> <a href="javascript:void(0);" v-for="(item,index) in monthList" @click="selectM(item-1)">{{item}}</a> </div> </div> </div> </template> <script> export default ({ props: ['dateToolsKey','trainDateList','trainDateFullList'], data(){ return { yearList:[2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022], monthList:[1,2,3,4,5,6,7,8,9,10,11,12], weekList:[], dayList:[],//所有的天数列表,前面空位补0 dayFullList:[],//所有的天数列表,前面空位补0 panelYear:'',//仪表盘显示的年 panelMonth:'',//仪表盘显示的月(从0开始) panelDay:'',//仪表盘显示的天(从1开始) firstDay:'',//每月第一天 lastDay:'',//每月最后一天也即每月多少天 firstDayisWhat:'',//第一天星期几0-6(星期日到星期六) showDropDownYM:false, } }, filters:{ filterDay(value){ return parseInt(value.slice(-2)); } }, methods:{ dateInit(year=(new Date()).getFullYear(),month=(new Date()).getMonth()){ let self = this; let y = year; let m = month; self.panelYear = year; self.panelMonth = month; self.firstDay = (new Date(y,m,1)).getDate();//每月第一天 self.lastDay = (new Date(y,m+1,0)).getDate();//每月最后一天也即每月多少天 self.firstDayisWhat = (new Date(y,m,1)).getDay();//第一天星期几0-6(星期日到星期六) let beginTmp = new Array(self.firstDayisWhat).fill(0);//初始化长度为3的数组并填充0 let lastTmp = [];//初始化长度为当月天数的数组并填充为0-30或0-31 let lastFullTmp = [];//初始化完整的月的每天格式为年月日20180627 for (let i=1;i<=self.lastDay;i++){ lastTmp.push(i); lastFullTmp.push(''+self.panelYear+self.addPreZero(self.panelMonth+1)+self.addPreZero(i)); } self.dayList=[...beginTmp,...lastTmp];//用结构的方式生成新日期数组 self.dayFullList = [...beginTmp,...lastFullTmp];//用结构的方式生成年月日完整的新日期数组 }, subMonth(){ let self = this; if(self.panelMonth>0){ self.panelMonth--; } }, addMonth(){ let self = this; if(self.panelMonth<11){ self.panelMonth++; } }, getCurrentDay(currentDay){ this.panelDay = currentDay; }, selectYM(){ let self = this; self.showDropDownYM = true; }, selectY(year){ let self = this; self.panelYear = year; }, selectM(month){ let self = this; self.panelMonth = month; self.showDropDownYM=false; }, addPreZero(num){//小于9的需要添加0前缀 return (num>9) ? num:('0'+num); }, removePreZero(num){//小于9的需要去除0前缀 return parseInt(num); } }, watch: { panelMonth(newVal,oldVal){//检测月份变化 this.dateInit(this.panelYear,this.panelMonth); }, panelYear(newVal,oldVal){//检测年份变化 this.dateInit(this.panelYear,this.panelMonth); }, panelDay(newVal,oldVal){//检测具体日期变化 this.$emit('topDateEvent'+this.dateToolsKey,newVal); } }, mounted(){ this.dateInit(); } }) </script> <style scoped> button{ background-color:#fff; cursor:pointer; } .date-btn,.date-middle{ color:#333!important; } .date-tools{ position:relative; /* margin-top:80px; */ display:inline-block; 310px; height:272px; overflow: hidden; border:1px solid #eee; } .date-btn{ 34px; height:34px; border-radius:50%; } .date-btn:hover{ color:#fff; background-color:#0A81E5; opacity:0.6; } .date-years{ margin:14px 20px 0 20px; display:flex; justify-content:space-between; } .date-weeks{ display: flex; justify-content:space-between; } .date-weeks span{ display:inline-block; 44px; height:34px; line-height:34px; text-align:center; } .date-days{ /* margin-top:14px; */ } .date-days button{ display: inline-block; 44px; height:36px; background-color:#fff; } .date-days a{ color:#000; display:inline-block; 34px; height:34px; line-height:34px; border-radius:50%; text-align:center; } .date-days a.active{ cursor:pointer; color:#fff; background-color:#0A81E5; } .date-days a:hover{ color:#fff; background-color:#0A81E5; opacity:0.6; } .drop-down-ym{ position:absolute; top:0; left:0; 310px; height:272px; background-color:rgba(255,255,255,0.9); display: flex; justify-content:space-between; } .drop-down-y,.drop-down-m{ 155px; height:272px; overflow:auto; padding:5px; /* display: flex; flex-direction:column; */ } .drop-down-y::-webkit-scrollbar,.drop-down-m::-webkit-scrollbar{ display: none; } .drop-down-y{ } .drop-down-m{ } .drop-down-y a,.drop-down-m a{ color:#000; text-align:center; display: inline-block; 100%; height:30px; line-height:30px; font-size:18px; margin:0 0 5px 0; } .drop-down-y a:hover,.drop-down-m a:hover{ color:#fff; background-color:rgba(10, 130, 229, 0.774); border-radius:5px; } .drop-down-y a.active,.drop-down-m a.active{ color:#fff; background-color:#0A81E5; border-radius:5px; } </style>
引用方式为:
<dateTools
:dateToolsKey="2" (每个日历控件特定的key值,如果key值一样,易发生css的样式冲突)
:trainDateList="trainDateList2" (需要特定操作的日期部分,可以直接传日期数组(1-30)例如[12,17,30])
:trainDateFullList="trainDateFullList" (需要特定操作的完整日期部分,可以直接传日期数组(1-30)例如['20180102','20120312'])
ref="topDateTools2" (refs名)
@topDateEvent2="topDateFun2" (子组件可以操作父组件的方法‘topDateFun2’)
></dateTools>