项目需要,需要一个日历表组件,产品狗嫌弃第三方提供的组件样式太丑,功能不全,带刀和产品理论奈何产品有枪。无奈只能自己写一个,发布完这条博客我就提离职,再也不和产品多BB。
Html=>
`<template>

<div class="calender">  <div class="calender-title-wrapper">    <div class="calender-title">      <div class="calender-arrow-item left2" v-if="false"></div>      <div class="calender-arrow-item left1" @click="month--"></div>      <div class="calender-Date-text">{{year}}年{{month}}月</div>      <div class="calender-arrow-item right1" @click="month++"></div>      <div class="calender-arrow-item right2" v-if="false"></div>    </div>  </div>  <div class="calender-content-wrapper">    <div class="calender-days-wrapper">      <div class="calender-days">日</div>      <div class="calender-days">一</div>      <div class="calender-days">二</div>      <div class="calender-days">三</div>      <div class="calender-days">四</div>      <div class="calender-days">五</div>      <div class="calender-days">六</div>    </div>    <div class="calender-content">      <div class="calender-item-wrapper"           v-for="item in daysArr"           :class="{'no-current-day':item.month!=month,                    active:item === clickItemObj,                    currentDay:item.day===_CurrentDate.day&&                               item.month===_CurrentDate.month&&                               item.year===_CurrentDate.year}"           @click="_clickDaysItem(item)"      >        <div class="calender-item">{{item.day}}</div>        <div class="tem-wrapper">          <span class="temp" v-for="d in markArr" :style="{background: d.color}" v-if="_visibleTemp(d,item)"></span>        </div>      </div>    </div>    <div class="calender-mask-wrapper">      <div class="calender-mask-item" v-for="item in markArr">        <span class="tem" :style="{background:item.color}"></span>        <span class="text">{{item.name}}</span>      </div>    </div>  </div></div>

</template>`
js=>

<script>    export default {        name: "calender",        props:{          markArr:{            type:Array,            default(){              return []            }          }        },        data(){          return {            day:'',            month:'',            year:'',            currentDays:'',            daysArr:[],            clickItemObj:{}          }        },        mounted() {          this._getCurrentDate()        },        methods:{          //点击日期          _clickDaysItem(item){            //选中日期标记与解除标记            if(this.clickItemObj === item){              this.clickItemObj = {}            }else {              this.clickItemObj = item            }            //非当前月份跳转            if(item.month!=this.month){              this.month = item.month            }            //传入事件筛选回返            this._user_defined_events(item)          },          //mark渲染          _user_defined_events(item){            for(let i=0;i<this.markArr.length;i++){              if(this.markArr[i].days.includes(`${item.year}-${item.month}-${item.day}`)){                this.$emit(this.markArr[i].clickEvent,item)              }            }          },          //是否显示mark          _visibleTemp(d,item){            let dateStr = `${item.year}-${item.month}-${item.day}`            return d.days.includes(dateStr)          },          //获取月份天数          _getDaysForMonth(year,month,type){            let temp=new Date(year,month,type);            let day = new Date(temp.getTime() - 864e5).getDate();            this.currentDays = day            this._getFirstDaysForMonth(this.year,this.month)          },          //获取当前日期          _getCurrentDate(){            let date = new Date()            this.day = date.getDate()            this.month = date.getMonth()+1            this.year = date.getFullYear()            this._getDaysForMonth(this.year,this.month,1)          },          //获取切换页月份第一天是周几与最后一天并获取月前与月后填补数组          _getFirstDaysForMonth(year,month){            let weekdays = new Date(`${year}-${month}-01`).getDay()            let beforeMonthDaysArr = []            let currentMonthDaysArr = []            let afterMonthDaysArr = []            //获取上一月总天数            if(month){              let temp=new Date(year,month-1,1);              let day = new Date(temp.getTime() - 864e5).getDate();              for(let i=0;i<day;i++){                beforeMonthDaysArr.push({                  year:year,                  month:month-1,                  day:i+1                })              }              beforeMonthDaysArr.splice(0,beforeMonthDaysArr.length-weekdays)            }else{              //12月            }            //获取当前月总天数            let temp=new Date(year,month,1);            let day = new Date(temp.getTime() - 864e5).getDate();            let afterWeekdays = new Date(`${year}-${month}-${day}`).getDay()            for(let i=0;i<day;i++){              currentMonthDaysArr.push({                year:year,                month:month,                day:i+1              })            }            if(beforeMonthDaysArr.length+currentMonthDaysArr.length+6-afterWeekdays===35){              for(let i=0;i<13-afterWeekdays;i++){                afterMonthDaysArr.push({                  year:year,                  month:month+1,                  day:i+1                })              }            }else{              for(let i=0;i<6-afterWeekdays;i++){                afterMonthDaysArr.push({                  year:year,                  month:month+1,                  day:i+1                })              }            }            this.daysArr = [...beforeMonthDaysArr,...currentMonthDaysArr,...afterMonthDaysArr]            //获取下一月总天数          }        },        watch:{          'month'(){            if(this.month===0){              this.month = 12              this.year--            }            if(this.month===13){              this.month = 1              this.year++            }            this._getDaysForMonth(this.year,this.month,1)          }        },        computed:{          _CurrentDate(){            let date = new Date()            let {day,month ,year} = {              day:date.getDate(),              month:date.getMonth()+1,              year:date.getFullYear()            }            return {day,month ,year}          }        }    }</script>

css=>
tips:我用的css解析器是stylus,用less和sass之类的大佬麻烦动动你们的小手加个花括号

<style scoped lang="stylus">  .calender    text-align center    min-width 280px    height 400px    .calender-title-wrapper      height 44px      line-height 44px      .calender-title        display flex        margin 0 auto        width 280px        .calender-arrow-item          flex 0 0 40px          cursor pointer          &.left1            background url("icon_left.svg") no-repeat center          &.left2            background url("icon_left2.svg") no-repeat center          &.right1            background url("icon_right.svg") no-repeat center          &.right2            background url("icon_right2.svg") no-repeat center        .calender-Date-text          flex 1          color #424242          font-size 16px    .calender-content-wrapper      .calender-days-wrapper        display flex        height 44px        line-height 44px        margin-bottom 11px        .calender-days          flex 1          color #A7A7A7          font-size 14px      .calender-content        .calender-item-wrapper          position relative          float left          width 14.285%          height 44px          line-height 44px          color #686868          cursor pointer          .tem-wrapper            position absolute            left 50%            height 10px            width 40px            transform translate3d(-50%,35px,0)            font-size 0            .temp              position relative              display inline-block              line-height 10px              width 6px              height 6px              background #4fff41              border-radius 3px              top -16px              margin 0 2px          .calender-item            position absolute            left calc(50% - 20px)            top calc(50% - 20px)            height 40px            width 40px            border-radius 20px            line-height 40px            &:hover              background #FFC912          &.no-current-day            color #DCDCDC          &.currentDay            color #ffffff            .calender-item              background #FFC912          &.active            color #ffffff            .calender-item              background #FFC912      .calender-mask-wrapper        height 37px        .calender-mask-item          height 37px          line-height 37px          width 25%          float left          .tem            margin-right 3px            display inline-block            height 8px            width 8px            border-radius 4px          .text            font-size 12px</style>

给各位大佬呈上APP.vue中的调用,以及参数详细用法
App.vue中的@test1事件是在在入参markArr中定义的,其中在markArr中color是标记日期的样式颜色,name是显示的样式名称,days是日期数组,clickEvent就是自定义事件名称

<template>  <div id="app">    <calender      @test1="test"      :markArr="[      {        color:'#76ff19',        name:'测试一',        days:['2019-5-8','2019-5-11','2019-5-14','2019-5-22'],        clickEvent:'test1'      },      {        color:'#ff1323',        name:'测试二',        days:['2019-5-9','2019-5-11','2019-5-3','2019-5-1'],        clickEvent:'test2'      },      {        color:'#ffc518',        name:'测试三',        days:['2019-5-18','2019-5-11','2019-5-7','2019-5-4'],        clickEvent:'test3'      },      {        color:'#ff26fc',        name:'测试四',        days:['2019-5-28','2019-5-11','2019-5-30','2019-5-31'],        clickEvent:'test4'      }      ]"    ></calender>    <!--<backwards></backwards>-->  </div></template><script>  import calender from './components/calender/calender'  import backwards from './components/backwards/backwards'export default {  name: 'App',  components:{    calender,    // backwards  },  methods:{    test(item){      console.log(item)    }  }}</script><style lang="stylus">#app  position absolute  height 100%  width 100%</style>

丢个成果图

是不是很丑?我故意的,想要好看自己改去吧,大致功能全都实现了