先看一下效果吧,畢竟不知道我寫的標題表達得夠不夠明確,

有沒有被帥到?標題說的日歷查看器就是這個,那么下面我們來聊聊究竟該怎么實作這個強大好看(有點自戀)的日歷查看(選擇器)吧,
先具體說一下思路吧:
這個日歷查看器其實最大的難點是怎么把月份和周的資料給對應上,其實利用陣列很好解決這個問題,我們可以將月份的資料存入到陣列中,日歷表渲染就把這個陣列遍歷一下就好了,但在存入的時候,做一下小小的判斷去給里面加幾個空字符,那這個空字符是干嘛的呢?看下面一張圖:

空字符對應的就是紅色框框中的內容,圖片日歷表中的陣列是這樣子的:["","",1,2,3,......];一直到30號,30號后面就不必再加了,
上面就是基本的一個思路,下面看看應該怎么去做吧!
第一步,我們先創建一個靜態的資料渲染先:
我把這個日歷選擇器分為兩個部分,一個部分是操作那個部分,也就是有前進后退按鈕那一個版塊,另一個部分就是日歷表,顯示資料的部分,
先把第一部分實作,代碼如下:
<!--日歷控制器start--> <view class="hours-calendar flex-content border-top p-18"> <view class="flex-content remote-ctr"> <image src="/images/agent/pre-icon.png" bindtap="preYearFn"></image> <view class="margin-42 color-gray">{{years}}</view> <image src="/images/agent/next-icon.png" bindtap="nextYearFn"></image> </view> <view class="flex-content remote-ctr ml-27"> <image src="/images/agent/pre-icon.png" bindtap="preMonthFn"></image> <view class="margin-42 color-gray">{{months}}月</view> <image src="/images/agent/next-icon.png" bindtap="nextMonthFn"></image> </view> <view class="ml-auto back-btn" bindtap="backToFn"> 回到今天 </view> </view> <!--日歷控制器end-->
上面是.wxml檔案的部分,那些圖片其實是左右箭頭類的,最后會給大家貼一下,有需要的朋友可以自行下載喔!
接下來看看樣式代碼:
.hours-calendar{ padding: 35rpx 48rpx; background-color: #ffffff; } .remote-ctr image{ width: 19rpx; height: 35rpx; } .margin-42{ margin: 0 42rpx; } .ml-27{ margin-left: 27rpx; } .back-btn{ color: #ec6941; border-radius: 10rpx; border: 2rpx solid #ec6941; padding: 6rpx 21rpx; } .calendar-content{ padding-bottom: 30rpx; background-color: #ffffff; }
全域中公用的樣式:
.flex-content{ display: flex; align-items: center; } .border-top{ border-top: 2rpx solid #e8e8e8; } .color-gray{ color: #a0a0a0; } .ml-auto{ margin-left: auto; }
實作第二部分日歷表,同樣利用強大的flex布局,然后讓它去自動換行就ok了
<view class="calendar-content p-18 color-gray border-top"> <view class="flex-content week"> <view>一</view> <view>二</view> <view>三</view> <view>四</view> <view>五</view> <view>六</view> <view>日</view> </view> <view class="flex-wrap week"> <view data-day="{{item}}" wx:for="{{30}}" wx:key="key">{{item}}</view> </view> </view>
加上樣式:
.calendar-content{ padding-bottom: 30rpx; background-color: #ffffff; } .week view{ width: 64rpx; height: 64rpx; text-align: center; line-height: 64rpx; margin-left: 38rpx; margin-top: 10rpx; } .is-today{ border-radius: 50%; background-color: #dfdfdf; position: relative; } .is-today::after{ content: "今天"; position: absolute; bottom: -20rpx; left: -3rpx; font-size: 12rpx; width: 70rpx; } .se-day{ border-radius: 50%; background-color: #ec6941; color: #ffffff; }
這樣一個靜態的日歷表就出來了,效果如下:

有個0?這是陣列遍歷的慣性,大家知道就好了,
那么接下來就是我們的重點了,究竟怎么讓周和月份對應上?
先創建一個日歷js方法檔案,calendar.js
然后貼出代碼:
/** * 回傳月份陣列 * @param year * @param month * @returns {*[]} */ const getMonthList = function (year, month) { let date = new Date(); if(year){ date.setFullYear(year); date.setMonth(month - 1); date.setDate(1); let weekIndex = (date.getDay() - 1) < 0 ? 6 : (date.getDay() - 1); //獲取本月總天數方法---將當前月份加1,下移到下一個月 console.log(month + ',設定的月份為:' + date.getMonth()); console.log('設定的禮拜為:' + weekIndex); date.setMonth(date.getMonth() + 1); //將當前日期置為0 date.setDate(0); console.log('獲取的天數為:' + date.getDate()); //再獲取天數即取上一個月的最后天數 let days = date.getDate(); let monthList =[]; //周幾開始加上總天數,就是所生產陣列的總個數 for(let i = 0; i < (weekIndex + days); i++){ if(weekIndex > i){ monthList.push(''); }else if((i) < (days + weekIndex + 1)){ monthList.push((i + 1) - weekIndex); }else { monthList.push(''); } } return monthList; } } module.exports = { getMonthList: getMonthList, }
上述的思路就跟開篇上將的是一樣的,可以對照上面一起看,
有了這個方法之后,它可以根據我們傳遞的年份和月份,把一個帶有空字符處理好的陣列回傳給我們,
然后我們稍稍修改一下原來那個遍歷的wx:for那里的代碼:
<view class="{{item === isToday ? 'is-today' : ''}} {{item === selectDay ? 'se-day' : ''}}" data-day="{{item}}" wx:for="{{calendarList}}" wx:key="key" bindtap="selectDayFn">{{item}}</view>
在生命周期函式加載的時候,自動獲取本月的日歷表:
/** * 生命周期函式--監聽頁面加載 */ onl oad: function (options) { this.setData({ groupId: Number(options.groupId), }); wx.setNavigationBarTitle({ title: options.name + '-工時' }); this.backToFn(); },
上面用到的backToFn其實就是一個回到今天的函式,不過是跟初始加載是一樣的,
/** * 初始化當天日期資料 */ backToFn(){ let _date = new Date(); this.resetDataFn( _date.getFullYear(),_date.getMonth() + 1,_date.getDate()); },
什么?又包含了一個函式?這個resetDataFn是重點,下面會有四個函式會公用到,編程思想嘛,當然是能拆分就盡量拆分,
/** * 資料重置 * @param years 年份 * @param months 月份 * @param days 天 */ resetDataFn(years, months, days = this.data.isToday){ this.setData({ years: years, months: months, isToday: days, calendarList: calendar.getMonthList(years,months), }) },
資料忘記初始化了:
下面我們在小程式頁面js檔案中宣告的幾個變數:
data: { calendarList: [], years: 0, months: 0, isToday: 0, selectDay: 0, },
calendarList是日歷表陣列,years是年份,months是月份,isToday是天數,selectDay是被點擊的天數(后面會用到),
等等,似憾訓忘記了什么東西?還沒實作怎么選擇呢?
變數宣告好了,再來什么幾個函式:Pages({})下,
/** * 上一年 */ preYearFn(){ let _date = new Date(); console.log(`${this.data.months},${_date.getMonth() + 1}`); let _days = this.data.years - 1 === _date.getFullYear() && (_date.getMonth() + 1) === this.data.months ? _date.getDate() : 0; this.resetDataFn(this.data.years - 1, this.data.months, _days); }, /** * 下一年 */ nextYearFn(){ let _date = new Date(); let _days = this.data.years + 1 === _date.getFullYear() && (_date.getMonth() + 1) === this.data.months ? _date.getDate() : 0; this.resetDataFn(this.data.years + 1, this.data.months, _days); }, /** * 上一月 */ preMonthFn(){ let _date = new Date(); let _months = this.data.months - 1 === 0 ? 12 : this.data.months - 1; let _years = this.data.months - 1 === 0 ? this.data.years - 1 : this.data.years; let _days = (_date.getMonth() + 1) === _months && this.data.years === _date.getFullYear() ? _date.getDate() : 0; this.resetDataFn(_years, _months, _days); }, /** * 下一個月 */ nextMonthFn(){ let _date = new Date(); let _months = this.data.months + 1 === 13 ? 1 : this.data.months + 1; let _years = this.data.months + 1 === 13 ? this.data.years + 1 : this.data.years; let _days = (_date.getMonth() + 1) === _months && this.data.years === _date.getFullYear() ? _date.getDate() : 0; this.resetDataFn(_years, _months, _days); },
上面就是對應了四個按鈕:

就這樣,一個強大霸氣的日歷選擇查看器就完成了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/102414.html
標籤:JavaScript
上一篇:使用es6模塊化后打開頁面報錯
