使用Vue写一个datepicker的示例(2)

computed: {
 dateList () {
  //获取当月的天数
  let currentMonthLength = new Date(this.tmpMonth, this.tmpMonth + 1, 0).getDate()
  //先将当月的日期塞入dateList
  let dateList = Array.from({length: currentMonthLength}, (val, index) => {
   return {
    currentMonth: true,
    value: index + 1
   }
  })
  //获取当月1号的星期是为了确定在1号前需要插多少天
  let startDay = new Date(this.year, this.tmpMonth, 1).getDay()
  //确认上个月一共多少天
  let previousMongthLength = new Date(this.year, this.tmpMonth, 0).getDate()
 }
 //在1号前插入上个月日期
 for(let i = 0, len = startDay; i < len; i++){
  dateList = [{previousMonth: true, value: previousMongthLength - i}].concat(dateList)
 }
 //补全剩余位置
 for(let i = 0, item = 1; i < 42; i++, item++){
  dateList[dateList.length] = {nextMonth: true, value: i}
 }
 return dateList
}

这里用Array.from来初始化了一个数组,传入一个Array Like,转化成数组,在拼接字符串时候采用了arr[arr.length]和[{}].concat(arr)这种方式,因为在JsTips上学到这样做性能更好,文章的最后会贴出相关链接。
这样,日期列表就构建好了,在template中使用v-for循环渲染出来

<ul class="date-list">
 <li v-for="item in dateList"
  v-text="item.value" 
  :class="{preMonth: item.previousMonth, nextMonth: item.nextMonth,
   selected: date === item.value && month === tmpMonth && item.currentMonth, invalid: validateDate(item)}"
  @click="selectDate(item)">
 </li>
</ul>

样式上就可以自己发挥了,怎么喜欢怎么写。需要注意的是循环日期可能会出现上个月或这个月的日期,我通过previuosMonth,currentMonth和nextMonth分别做了标记,对其他功能提供判断条件。
年份和月份的列表都是差不多的道理,年份列表的初始值我直接写在了data里,以当前年份为第一个,为了和月份保持一致,每次显示12个,都通过v-for渲染。

data () {
 return {
  yearList: Array.from({length: 12}, (value, index) => new Date().getFullYear() + index)
 }
}

选择日期功能

选择顺序是:年 -> 月 -> 日,所以我们可以通过一个状态变量来控制panel中显示的内容,绑定适合的函数切换显示状态。

<div>
 <div class="type-year" v-show="panelType === 'year'">
  <ul class="year-list">
   <li v-for="item in yearList"
    v-text="item"
    :class="{selected: item === tmpYear, invalid: validateYear(item)}" 
    @click="selectYear(item)"
   >
   </li>
  </ul>
 </div>
 <div class="type-month" v-show="panelType === 'month'">
  <ul class="month-list">
   <li v-for="item in monthList"
    v-text="item | month language"
    :class="{selected: $index === tmpMonth && year === tmpYear, invalid: validateMonth($index)}" 
    @click="selectMonth($index)"
   >
   </li>
  </ul>
 </div>
 <div class="type-date" v-show="panelType === 'date'">
  <ul class="date-list">
   <li v-for="item in dateList"
    v-text="item.value" 
    track-by="$index" 
    :class="{preMonth: item.previousMonth, nextMonth: item.nextMonth,
     selected: date === item.value && month === tmpMonth && item.currentMonth, invalid: validateDate(item)}"
    @click="selectDate(item)">
   </li>
  </ul>
 </div>
</div>

      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/33.html