码迷,mamicode.com
首页 > Web开发 > 详细

Vue.js(18)之 封装calendar组件

时间:2019-06-07 11:16:58      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:visible   template   取消   mint   当前日期   EAP   title   ges   方法   

效果

技术图片

 

 

需求

1、实现一个日历组件,如图:

 技术图片

2、显示某天的事项:

技术图片

3、事项是模拟父组件请求接口返回的,数据格式如下:

[
        {
          id: ‘232‘,
          date: ‘2019-06-01‘,
          info: ‘我要去吃大餐‘
        },
        {
          id: ‘292‘,
          date: ‘2019-06-06‘,
          info: ‘我要去吃大餐‘
        },
        {
          id: ‘292‘,
          date: ‘2019-06-07‘,
          info: ‘我要去吃大餐‘
        },
        {
          id: ‘369‘,
          date: ‘2019-06-30‘,
          info: ‘我要去吃大餐‘
        }
      ]

4、把事项添加到日历组件中,数据格式如下:

技术图片

 

代码解析

父组件页面:

<template>
  <div class="test-container">
    <h1>Test页面,测试组件</h1>
    <!-- 日历 -->
    <calendar v-if="calendarVisible" @getDateInfo="getDateInfo" :propsInfoList="propsInfoList" :propsTime="propsTime"></calendar>
  </div>
</template>

<script>
import calendar from @/components/Calendar/Calendar.vue
export default {
  name: test,
  components: {
    "calendar": calendar
  },
  data() {
    return {
      calendarVisible: true,
      propsTime: ‘‘,
      propsInfoList: ‘‘,
      middle: [
        {
          id: 232,
          date: 2019-06-01,
          info: 我要去吃大餐
        },
        {
          id: 292,
          date: 2019-06-06,
          info: 我要去吃大餐
        },
        {
          id: 292,
          date: 2019-06-07,
          info: 我要去吃大餐
        },
        {
          id: 369,
          date: 2019-06-30,
          info: 我要去吃大餐
        }
      ]
    }
  },
  created() {
    this.propsInfoList = JSON.stringify(this.middle)
    this.propsTime = this.getToday()
  },
  mounted() {
    window.alert(测试时间为19年 5、6、7月,完成是在6月)
  },
  methods: {
    // 格式化当前日期 YYYY-MM-DD
    getToday() {
      let nowDate = new Date()
      let yy = nowDate.getFullYear().toString()
      let mm = (nowDate.getMonth() + 1 + ‘‘).padStart(2,0)
      let dd = (nowDate.getDate() + ‘‘).padStart(2,0)
      // let hh = nowDate.getHours().toString().padStart(2,‘0‘)
      // let mt = (nowDate.getMinutes() + ‘‘).padStart(2,‘0‘)
      // let ss = (nowDate.getSeconds() + ‘‘).padStart(2,‘0‘)
      return `${yy}-${mm}-${dd}` // -${hh}-${mt}-${ss}
    },
    // 组件传值
    getDateInfo(year, month) {
      let _this = this
      _this.propsTime = `${year}-${month}`
      _this.calendarVisible = false
      setTimeout(() => {
        _this.propsInfoList = []
        let middle
        if(month == 05) {
          middle  = [
            {
              id: 232,
              date: 2019-05-10,
              info: 我要去吃小餐
            }
          ]
        } else if (month == 06) {
          middle = _this.middle
        } else if (month == 07) {
          middle  = [
            {
              id: 232,
              date: 2019-07-10,
              info: 我要去吃小餐
            }
          ]
        } else {
          middle = ‘‘
        }
        _this.propsInfoList = JSON.stringify(middle)
        _this.calendarVisible = true
      }, 100)
    }
  }
}
</script>

日历子组件:

<template>
  <div class="calendar-container">
    <h1>calendar</h1>
    <div class="show-date" @click="clickData">{{showDate}}</div>
    <div class="now-time">今日:{{exactTime}}</div>
    <div class="calendar">
      <ul class="calendar-header">
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
      </ul>
      <ul class="calendar-body">
        <li class="calendar-row" v-for="(item, index) in JSON.parse(calendarData)" :key="index">
          <span v-for="(subItem, subIndex) in item" :class="[subIndex == 0 || subIndex == 6? ‘weekend‘: ‘weekday‘, subItem.type == ‘1‘? ‘exact-time‘: ‘‘, subItem.type == ‘0‘? ‘already-time‘: ‘‘, subItem.type == ‘2‘? ‘soon-time‘: ‘‘]" @click="showInfo(subItem)" :key="subIndex">
            {{subItem.date}}
          </span>
        </li>
      </ul>
    </div>
    <mt-popup v-model="popupVisible" position="bottom">
      <mt-picker :slots="slots" :showToolbar="true" :visibleItemCount="5" :itemHeight="itemsHeight" ref="picker">
        <img src="@/assets/images/picker_cancel.png" class="picker_cancel" v-on:click="cancelFunc()">
        <img src ="@/assets/images/picker_sure.png" class="picker_sure" v-on:click="sureFunc()">
      </mt-picker>
    </mt-popup>
  </div>
</template>

日历子组件逻辑:

import { MessageBox } from ‘mint-ui‘
export default {
  name: "calendar",
  props: {
    propsTime: String,
    propsInfoList: String
  },
  data() {
    return {
      time: ‘‘,
      infoList: ‘‘,
      calendarData: [],
      showDate: ‘‘,
      exactTime: ‘‘,
      itemsHeight: 95 * window.screen.height / 1334,
      popupVisible: false,
      slots: []
    }
  },
  created() {
    this.infoList = this.propsInfoList
    this.time = this.propsTime.split(‘-‘)
    const date = this.getToday()
    this.exactTime = date.slice(0,3).join(‘-‘)
    this.getCalendar(...(this.time))
    this.getSlotsArray(...(date.slice(0,2)))
  },
  methods: {
    // 日历组件
    getCalendar(year, month) {
      let _this = this
      const rightNow = _this.exactTime
      _this.showDate = `${year}-${month
      const firstDate = new Date(year, month - 1, 1)
      const firstDay = firstDate.getDay()
      const isLeapYear = year % 100 == 0? year % 400 == 0? 1: 0: year % 4 == 0 ? 1: 0
      const monthArray = [31, 28 + isLeapYear, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
      const weeekLines =Math.ceil((monthArray[month - 1] + firstDay)/7)
      let calendar = []
      for(let i = 0; i < weeekLines; i++) {
        let weeekLinesInfo = []
        for(let j = 0; j < 7; j++) {
          const cellNo = i * 7 + j
          const datePerLine = cellNo - firstDay + 1
          if(datePerLine <= 0 || datePerLine > monthArray[month - 1]) {
            let outOfMonth = {
              "type" : ‘null‘,
              "date" : ‘‘
            }
            weeekLinesInfo[j] = outOfMonth
          } else {
            let day = (datePerLine + ‘‘).padStart(2,‘0‘)
            let inOfMonth = {
              "type" : ‘‘,
              "date" : day,
              "isDone": ‘‘,
              "infor": ‘‘
            }
            const propsDate = `${year}-${month}-${day}`
            if(propsDate == rightNow){
              inOfMonth.type = "1"
            }
            const reservations = JSON.parse(_this.infoList)
            for(let k = 0; k < reservations.length; k++) {
              if(propsDate == reservations[k].date){
                // inOfMonth.type = "1"
                inOfMonth.infor = reservations[k].info
                if(rightNow == reservations[k].date) {
                  inOfMonth.type = "1"
                  inOfMonth.isDone = "doing"
                } else if (rightNow > reservations[k].date) {
                  inOfMonth.type = "0"
                  inOfMonth.isDone = "pass"
                } else if (rightNow < reservations[k].date) {
                  inOfMonth.type = "2"
                  inOfMonth.isDone = "will"
                }
              }
            }
            weeekLinesInfo[j] = inOfMonth
          }
        }
        calendar.push(weeekLinesInfo)
      }
      window.console.log(calendar)
      _this.calendarData = JSON.stringify(calendar)
    },
    // 格式化当前日期 YYYY-MM-DD
    getToday() {
      let nowDate = new Date()
      let yy = nowDate.getFullYear().toString()
      let mm = (nowDate.getMonth() + 1 + ‘‘).padStart(2,‘0‘)
      let dd = (nowDate.getDate() + ‘‘).padStart(2,‘0‘)
      let hh = nowDate.getHours().toString().padStart(2,‘0‘)
      let mt = (nowDate.getMinutes() + ‘‘).padStart(2,‘0‘)
      let ss = (nowDate.getSeconds() + ‘‘).padStart(2,‘0‘)
      return [yy, mm, dd, hh, mt, ss]
      // return `${yy}-${mm}-${dd}-${hh}-${mt}-${ss}`
    },
    // 组装 picker 数组
    getSlotsArray(year, month){
      let _this = this
      let yearArray = []
      for(let i = -10 ; i <= 10 ; i ++){
        yearArray.push(year - 1 + i)
      }
      let monthArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
      let slots = [
        {
          values:yearArray,
          className:"slot1",
          defaultIndex: 11
        },
        {
          values:monthArray,
          className:"slot2",
          defaultIndex:month - 1
        }
      ]
      _this.slots = slots
    },
    // 显示日期弹窗
    clickData(){
      this.popupVisible = true
    },
    // 取消按钮
    cancelFunc(){
      this.popupVisible = false;
    },
    // 确认按钮
    sureFunc() {
      let _this = this
      _this.popupVisible = false
      const clickData = _this.$refs.picker.getValues()
      const year = clickData[0] + ‘‘
      const month = (clickData[1] + ‘‘).padStart(2,‘0‘)
      const day = _this.time[2]
      _this.getDateInfo(year, month)
      _this.getCalendar(year, month)
    },
    // 调用父组件定义的方法
    getDateInfo(year, month) {
      this.$emit(‘getDateInfo‘, year, month)
    },
    // 点击展示某天的事项信息
    showInfo(info) {
      let _this = this
      const infor = info
      if(infor.infor) {
        const [year, month] = _this.showDate.split(‘-‘)
        console.log(year, month, info)
        const titleDate = `${year}-${month}-${info.date}`
        const preview = info.infor
        MessageBox({
          title: titleDate,
          message: preview,
          showCancelButton: false,
          closeOnClickModal: true
        })
      }
    }
  }
}

 

其他:为了减少篇幅,省略样式

github地址

Vue.js(18)之 封装calendar组件

标签:visible   template   取消   mint   当前日期   EAP   title   ges   方法   

原文地址:https://www.cnblogs.com/houfee/p/10987447.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!