組件的三要素就是小程序定義的三種文件:js,wxml,wxss。因為js本身就是模塊化開發,所以這天然有利于組件化。wxml和wxss呢,定義了組件的皮膚,小程序的模板template標簽可以方便wxml的復用。至于wxss,沒有獨立出來,目前沒發現要怎么整合到獨立的組件中去,而不與其他的wxss發生耦合。
用法
// 如果模板是寫在單獨的wxml文件,則要inport,引入。路徑則是當前文件的相對路徑。
import>
需要注意的是data數據是有單獨的作用域的,只能使用data傳入的數據。具體的理解就是:
data: {
item: {
index: int
msg: string
time: string
},
index: int
msg: string
time: string
}
模板里面的數據實際顯示的是item的屬性,而不是和item同級的屬性。
模板還有一種用法
這樣就要傳入模板中用到的三個變量,而不是item一個對象。模板渲染的結果則是最外層的index屬性,而不是item的index屬性值。
…符號是擴展運算符,理解為將一個對象所以的屬性展開傳遞給模板,這樣的好處是不要傳遞多個,寫出的代碼更加簡潔。擴展運算符是ES6的特性,有興趣可以深入學習。
如果運用擴展運算符給模板傳入數據,像上面怎么去更新單個key的值呢?小程序提供了可以根據屬性路徑更新的方法:
// 更新單個key,
this.setData({
index: 1
});
/* 更新對象中的單個key
item: {
index: int
msg: string
time: string
}
*/
this.setData({
\'item.index\': 1
});
// path必須是字符串,不能是變量替代。下面是不行的
path = \'item.index\';
this.setData({
path: 1
});
雖然用法上是有點限制,但也避免了傳入一堆的參數給模板。值得注意的是入參data的item必須是有初始化值,否則會報錯。
舉一個日歷組件開發的實例,利用template和js就可以打造這樣一款組件了。
定義一個wxml文件和一個js文件,日期類有自己的作用域名,所以組件內部的事件導致數據更新的時候,還是要用頁面更新數據的方法this.setData,所以必須要將頁面對象傳遞給組件內部。
頁面調用組件:
// this 是當前頁面page對象,含有setData方法。
var calendar = new Calendar(this, function(date) {
that.setData({
date: date
})
});
// 當選擇日期變化的時候,組件內部事件: this.pageCtx 則是page上下文,即上面實例化組件入參的this對象。
changeCalendarTab(e) {
this.pageCtx.setData({
\'calendar_data.selectDateType\':
+e.target.dataset.tap
});
this.data.selectDateType = +e.target.dataset.tap;
this.changeCallBack && this.changeCallBack(this.getCurrentSelectDate());
}
這樣就完成了一個組件編寫,任何需要用到的地方都可以引入了。小程序一個不太好的地方是沒有包管理的概念,導致跨項目見的公共模塊復用起來比較麻煩。