zoukankan      html  css  js  c++  java
  • Vue.js之calendar组件

    效果

    需求

    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地址

  • 相关阅读:
    幸运的秘密
    125条常见的java面试笔试题大汇总之一
    转身离去
    古怪的问题
    125条常见的java面试笔试题大汇总之五
    125条常见的java面试笔试题大汇总之四
    125条常见的java面试笔试题大汇总之三
    关于PostGreSQL中的存储过程
    关于文件编码
    javascript高级程序设计(2)ECMAScript基础
  • 原文地址:https://www.cnblogs.com/houfee/p/10987447.html
Copyright © 2011-2022 走看看