簡陋至極:微信小程序日曆組件(思路)

最近在作微信小程序項目,其中涉及到日曆。一直以來,遇到日曆,就是網上隨便找個插件,此次心血來潮,想着本身去實現一下。此次不是封裝功能強大,健碩完美的組件,只是記錄一下,主體思路。更多功能還得根據項目須要,本身去挖掘、實現。(大佬輕噴)

圖片描述

思路分析

  • 首先最主要的一點,就是要計算出某年某月有多少天,其中涉及到大小月,閏、平年二月。

  • 其次,弄清楚每個月一號對應的是周幾。

  • 而後,有時爲填充完整,還需顯示上月殘餘天數以及下月開始幾天,這些又該如何展現。

  • 最後,根據本身項目需求實現其它細枝末節。

計算每個月天數

  • 按照通常思路,[1,3,5,7,8,10,12]這幾個月是31天,[2,3,6,9,11]這幾個月是30天,閏年2月29天,平年2月28天。每次須要計算天數時,都得如此判斷一番。方案可行,並且也是大多數人的作法。可是,這個方法,我卻以爲有些繁瑣。

  • 其實換一種思路,也何嘗不可。時間戳就是一個很好的載體。當前月一號零時的時間戳,與下月一號零時的時間戳之差,不就是當前月天數的毫秒數嘛。

    // 獲取某年某月總共多少天
        getDateLen(year, month) { 
            let actualMonth = month - 1;
            let timeDistance = +new Date(year, month) - +new Date(year, actualMonth);
            return timeDistance / (1000 * 60 * 60 * 24);
        },
  • 看到上述代碼,你可能會問,是否是還缺乏當月爲12月時的特殊判斷,畢竟涉及到跨年問題。固然,你無需擔憂,根據MDN中關於Date的表述,js已經爲咱們考慮好了這一點

    當Date做爲構造函數調用並傳入多個參數時,若是數值大於合理範圍時(如月份爲13或者分鐘數爲70),相鄰的數值會被調整。好比 new Date(2013, 13, 1)等於new Date(2014, 1, 1),它們都表示日期2014-02-01(注意月份是從0開始的)。其餘數值也是相似,new Date(2013, 2, 1, 0, 70)等於new Date(2013, 2, 1, 1, 10),都表示時間2013-03-01T01:10:00。

計算每個月一號是周幾

  • 呃,這個就不須要說了吧,getDay()你值得擁有

    // 獲取某月1號是周幾
        getFirstDateWeek(year, month) { 
            return new Date(year, month - 1, 1).getDay()
        },

每月的數據如何展現

  • 若是隻是簡單展現當月數據,那仍是很簡單的,獲取當月天數,依次遍歷,就能夠拿到當月全部數據。

    // 獲取當月數據,返回數組
        getCurrentArr(){ 
            let currentMonthDateLen = this.getDateLen(this.data.currentYear, this.data.currentMonth) // 獲取當月天數
            let currentMonthDateArr = [] // 定義空數組
            if (currentMonthDateLen > 0) {
                for (let i = 1; i <= currentMonthDateLen; i++) {
                    currentMonthDateArr.push({
                        month: 'current', // 只是爲了增長標識,區分上下月
                        date: i
                    })
                }
            }
            this.setData({
                currentMonthDateLen
            })
            return currentMonthDateArr
        },
  • 不少時候,爲了顯示完整,須要顯示上下月的殘餘數據。通常來講,日曆展現時,最大是7 X 6 = 42位,爲啥是42位,呃,本身去想一想吧。當月天數已知,上月殘餘天數,咱們能夠用當月1號是周幾來推斷出來,下月殘餘天數,正好用42 - 當月天數 -上月殘餘。

    // 上月 年、月
        preMonth(year, month) { 
            if (month == 1) {
                return {
                    year: --year,
                    month: 12
                }
            } else {
                return {
                    year: year,
                    month: --month
                }
            }
        },
    // 獲取當月中,上月多餘數據,返回數組
        getPreArr(){ 
            let preMonthDateLen = this.getFirstDateWeek(this.data.currentYear, this.data.currentMonth) // 當月1號是周幾 == 上月殘餘天數)
            let preMonthDateArr = [] // 定義空數組
            if (preMonthDateLen > 0) {
                let { year, month } = this.preMonth(this.data.currentYear, this.data.currentMonth) // 獲取上月 年、月
                let date = this.getDateLen(year, month) // 獲取上月天數
                for (let i = 0; i < preMonthDateLen; i++) {
                    preMonthDateArr.unshift({ // 尾部追加
                        month: 'pre', // 只是爲了增長標識,區分當、下月
                        date: date
                    })
                    date--
                }
            }
            this.setData({
                preMonthDateLen
            })
            return preMonthDateArr
        },
    // 下月 年、月
        nextMonth(year, month) { 
            if (month == 12) {
                return {
                    year: ++year,
                    month: 1
                }
            } else {
                return {
                    year: year,
                    month: ++month
                }
            }
        },
    // 獲取當月中,下月多餘數據,返回數組
        getNextArr() { 
            let nextMonthDateLen = 42 - this.data.preMonthDateLen - this.data.currentMonthDateLen // 下月多餘天數
            let nextMonthDateArr = [] // 定義空數組
            if (nextMonthDateLen > 0) {
                for (let i = 1; i <= nextMonthDateLen; i++) {
                    nextMonthDateArr.push({
                        month: 'next',// 只是爲了增長標識,區分當、上月
                        date: i
                    })
                }
            }
            return nextMonthDateArr
        },
  • 整合三組數據,就獲得了完整的當月數據,格式以下

    [
        {month: "pre", date: 30},
        {month: "pre", date: 31},
        {month: "current", date: 1},
        {month: "current", date: 2},
        ...
        {month: "current", date: 31},
        {month: "next", date: 1},
        {month: "next", date: 2}
    ]
  • 至於上下月切換,選擇某年某月等功能,無非就是參數變化而已,本身琢磨琢磨便可。

  • 骨架都有了,你想創造什麼樣的功能還不是手到擒來。

完整代碼 GitHub

相關文章
相關標籤/搜索