微信小程序開發05-日曆組件的實現

接上文:微信小程序開發04-打造本身的UI庫css

github地址:https://github.com/yexiaochai/wxdemohtml

咱們這裏繼續實現咱們的日曆組件,這個日曆組件稍微有點特殊,算是相對複雜的組件了,而後通常的日曆組件又會有不少的變化,因此咱們這裏實現最基本的標籤便可:git

 1 let View = require('behavior-view');
 2 const util = require('../utils/util.js');
 3 
 4 // const dateUtil = util.dateUtil;
 5 
 6 Component({
 7   behaviors: [
 8     View
 9   ],
10   properties: {
11     
12   },
13   data: {
14     weekDayArr: ['日', '一', '二', '三', '四', '五', '六'],
15     displayMonthNum: 1,
16 
17     //當前顯示的時間
18     displayTime: null,
19     //能夠選擇的最先時間
20     startTime: null,
21     //最晚時間
22     endTime: null,
23 
24     //當前時間,有時候是讀取服務器端
25     curTime: new Date()
26     
27   },
28 
29   attached: function () { 
30     //console.log(this)
31   },
32   methods: {
33    
34   }
35 })
 1 <wxs module="dateUtil">
 2   var isDate = function(date) {
 3     return date && date.getMonth;
 4   };
 5 
 6   var isLeapYear = function(year) {
 7     //傳入爲時間格式須要處理
 8     if (isDate(year)) year = year.getFullYear()
 9     if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) return true;
10     return false;
11   };
12 
13   var getDaysOfMonth = function(date) {
14     var month = date.getMonth(); //注意此處月份要加1,因此咱們要減一
15     var year = date.getFullYear();
16     return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
17   }
18 
19   var getBeginDayOfMouth = function(date) {
20     var month = date.getMonth();
21     var year = date.getFullYear();
22     var d = getDate(year, month, 1);
23     return d.getDay();
24   }
25 
26   var getDisplayInfo = function(date) {
27     if (!isDate(date)) {
28       date = getDate(date)
29     }
30     var year = date.getFullYear();
31 
32     var month = date.getMonth();
33     var d = getDate(year, month);
34 
35     //這個月一共多少天
36     var days = getDaysOfMonth(d);
37 
38     //這個月是星期幾開始的
39     var beginWeek = getBeginDayOfMouth(d);
40 
41     /*
42         console.log('info',JSON.stringify( {
43           year: year,
44           month: month,
45           days: days,
46           beginWeek: beginWeek
47         }));
48     */
49 
50     return {
51       year: year,
52       month: month,
53       days: days,
54       beginWeek: beginWeek
55     }
56   }
57 
58   module.exports = {
59     getDipalyInfo: getDisplayInfo
60   }
61 </wxs>
62 
63 
64 <view class="cm-calendar">
65   <view class="cm-calendar-hd ">
66     <block wx:for="{{weekDayArr}}">
67       <view class="item">{{item}}</view>
68     </block>
69   </view>
70   <view class="cm-calendar-bd ">
71     <view class="cm-month ">
72     </view>
73     <view class="cm-day-list">
74 
75       <block wx:for="{{dateUtil.getDipalyInfo(curTime).days + dateUtil.getDipalyInfo(curTime).beginWeek}}" wx:for-index="index">
76 
77         <view wx:if="{{index < dateUtil.getDipalyInfo(curTime).beginWeek }}" class="item active"></view>
78         <view wx:else class="item">{{index + 1 - dateUtil.getDipalyInfo(curTime).beginWeek}}</view>
79 
80       </block>
81 
82       <view class=" active  cm-item--disabled " data-cndate="" data-date="">
83 
84       </view>
85     </view>
86   </view>
87 </view>

這個是很是簡陋的日曆雛形,在代碼過程當中有如下幾點比較痛苦:github

① WXML與js間應該只有數據傳遞,根本不能傳遞方法,應該是兩個webview的通訊,而日曆組件這裏在WXML層由不得不寫一點邏輯web

② 原本在WXML中寫邏輯已經不太對了,而咱們引入的WXS,使用與HTML中的js片斷也有很大的不一樣小程序

這些問題,一度讓代碼變得複雜,而能夠看到一個簡單的組件,尚未複雜功能,涉及到的文件都太多了,這裏是調用層:微信小程序

<ui-calendar  is-show="" ></ui-calendar>

事實上,咱們以上數據根本不該該寫到data裏面,應該屬性傳遞,咱們這裏先爲了簡單實現功能,接下來咱們繼續完善這個組件,具體代碼請看git:服務器

這個日曆組件應該是在小程序中寫的最複雜的組件了,尤爲是不少邏輯判斷的代碼都放在了WXML裏面,根據以前的瞭解,小程序渲染在一個webview中,js邏輯在一個webview中,他這樣作的目的多是想讓性能更好,可是我這裏代碼寫起來事實上是有點痛苦的,咱們這裏開始組裝組件,將數據配置放到屬性上,開始組裝abstract-page,事實上我認爲日曆這種非全局組件原本不該該放到基類中:微信

① 由於Component提供的是一個標籤,並且涉及的文件不少,加上繼承關係很很差管理組件化

② 由於日曆組件事實上是一個標籤,因此咱們會有一個引入的基礎WXML,一個使用的js,徹底獨立一個文件更加複雜

③ 原本小程序或者複雜的頁面都應該組件化開發,因此咱們簡歷一個頁面級別的組件,分散到對應的頁面中

小程序像是給靈活的HTML&JS戴上了枷鎖,只容許在其容許的範圍靈活,咱們這裏嘗試對頁面進行再拆分:

1 <import src="./mod.searchbox.wxml" />
2 <view>
3   <template is="searchbox" />
4 </view>
5 <include src="./mod/calendar.wxml"/>
6 <include src="../../utils/abstract-page.wxml"/>
<ui-calendar displayTime="{{CalendarDisplayTime}}"
selectedDate="{{CalendarSelectedDate}}"
displayMonthNum="{{CalendarDisplayMonthNum}}"
is-show="{{isCalendarShow}}" ></ui-calendar>
 1 /*
 2 事實上一個mod就只是一個對象,只不過爲了方便拆分,將對象分拆成一個個的mod
 3 一個mod對應一個wxml,可是共享外部的css,暫時如此設計
 4 全部日曆模塊的需求所有再此實現
 5 */
 6 module.exports = {
 7   q: 1,
 8   ddd: function(){},
 9 
10   data: {
11     isCalendarShow: '',
12     CalendarDisplayMonthNum: 2,
13     CalendarDisplayTime: new Date(),
14     CalendarSelectedDate: null
15   }
16 }

核心代碼仍是在abstract-page裏面:

 1   //pageData爲頁面級別數據,mod爲模塊數據,要求必定不能重複
 2   initPage(pageData, mod) {
 3     //debugger;
 4     let _pageData = {};
 5     let key, value, k, v;
 6 
 7     //爲頁面動態添加操做組件的方法
 8     Object.assign(_pageData, this.getPageFuncs(), pageData);
 9 
10     //生成真實的頁面數據
11     _pageData.data = {};
12     Object.assign(_pageData.data, this.getPageData(), pageData.data || {});
13 
14     for( key in mod) {
15       value = mod[key];
16       for(k in value) {
17         v = value[k];
18         if(k === 'data') {
19           Object.assign(_pageData.data, v);
20         } else {
21           _pageData[k] = v;
22         }
23       }
24     }
25 
26     console.log(_pageData);
27     return _pageData;
28   }

這裏再改造一下,咱們基本的日曆組件便完成了80%了:

 1 /*
 2 事實上一個mod就只是一個對象,只不過爲了方便拆分,將對象分拆成一個個的mod
 3 一個mod對應一個wxml,可是共享外部的css,暫時如此設計
 4 全部日曆模塊的需求所有再此實現
 5 */
 6 module.exports = {
 7   q: 1,
 8   ddd: function(){},
 9   onCalendarDayTap: function (e) {
10     let data = e.detail;
11     var date = new Date(data.year, data.month, data.day);
12     console.log(date)
13     this.setData({
14       calendarSelectedDate: date
15     });
16   },
17   data: {
18     isCalendarShow: '',
19     calendarDisplayMonthNum: 2,
20     calendarDisplayTime: new Date(),
21     calendarSelectedDate: null
22   }
23 }

至此,咱們組件相關課題基本結束,接下來,咱們開始咱們的業務代碼

相關文章
相關標籤/搜索