一、摘要
組件是小程序整個語法中占比比較大的一部分,沒寫過組件可以說只懂了半個小程序。組件提供了類似頁面的生命周期與邏輯。相比於模板,組件能實現的功能更加全面,也更為強大。通過slot可以自由擴展組件,使組件更具有擴展性,使用起來也不會有太大的局限性。要說不足之處:在目前最新的2.4版本都不能實現組件的自定義數據。而且組件的使用還存在着一些bug。
二、正文
組件的相關說明官方文檔已經寫得十分清除,這里只對寫組件的相關技巧進行探討。
小程序為組件提供了一些配置字段,在相對於的字段添加自己的代碼可以得到一些效果(實際上大多數js框架都是這樣做的)。在properties字段下可以添加組件的屬性,這些屬性可以在使用組件的時候訪問並賦值。
properties: { isShow: { type: Boolean, value: false, observer: function (newVal) { this.setData({ mIsShow: newVal }); } }, title: { type: String, value: '提示' }, radius: { type: String, value: '12' }, src: { type: String, value: '' }, iconWidth: { type: String, value: '30' }, iconHeight: { type: String, value: '30' }, iconLeft: { type: String, value: '610' }, iconTop: { type: String, value: '25' }, titleColor: { type: String, value: '#000' }, titleSize: { type: String, value: '34' } },
上面給出了一系列的字段,注意字段需要設置type和value屬性,type決定了從組件外傳進來的參數會已何種數據類型解析。類如,如果給title字段傳入的是數組 title='{{ ["1", "2"] }}' ,但是它定義的是String類型,那么就相當於傳入的是 title='[1,2]' 。
還有一個十分好用的屬性,那就是observer屬性。可以看到isShow字段給了這個屬性。這個屬性是在該字段的值發生變化時候會調用observer的回調函數,因此可以在該函數中進行一些操作。最常用的就是在data字段定義組件的內部變量,然后在該函數中去改變內部變量,這樣就實現了類似頁面中的數據綁定的效果(實際上properties字段下的屬性都不是數據綁定的,也就是在組件外更改變量數值是不會影響到組件內部的模板的)。
最后我們來說說lifetimes字段,這個字段里面可以寫組件的生命周期函數,並且會覆蓋該字段外的生命中期函數(實際上可以直接寫生命周期函數的,不過還是建議寫在這個字段里面)。
lifetimes: { ready: function () { let that = this; const sysInfo = wx.getSystemInfoSync(); const query = wx.createSelectorQuery(); query.in(this).select('.component').boundingClientRect().selectViewport().scrollOffset() query.exec(function (res) { that.setData({ top: 0, left: 0, width: sysInfo.windowWidth, height: sysInfo.windowHeight }); }); }, },
說明一下:示例代碼是一個完整的自定義模態框組件。因為模態框需要實現遮罩效果,但是在小程序中屏幕的寬度是固定為750rpx,但是屏幕高度是根據這個固定寬度計算的,所有會存在不同手機的屏幕高度是不同的(例如iPhone6與iPhoneX)。所以這里需要動態計算屏幕的寬高(實際上你也可以設置一個非常大的高度,使目前市面上所有手機都支持,但這不是最好的實現方式)。這段代碼用到了組件的ready生命周期(因為這里需要訪問模板節點,只有ready后才能訪問節點)。然后在ready函數中去設置data字段的width和height。這個width和height是與模板進行了數據綁定。
<view class='component cus animated' hidden='{{ !isShow }}' style='width: {{ width }}px; height: {{ height }}px; top: {{ top }}px; left: {{ left }}px' catchtouchmove='onMove'> <view class='body' style='border-radius: {{ radius }}rpx'> <image class='image' wx:if='{{ src != undefined && src != "" ? true : false }}' src='{{ src }}' style='width: {{ iconWidth }}rpx; height: {{ iconHeight }}rpx; left: {{ iconLeft }}rpx; top: {{ iconTop }}rpx' catchtap='onTap'></image> <view class='image icon-cus' wx:if='{{ src != undefined && src != "" ? false : true }}' src='{{ src }}' style='font-size: {{ iconWidth }}rpx; left: {{ iconLeft }}rpx; top: {{ iconTop }}rpx' catchtap='onTap'></view> <text wx:if='{{ title != undefined && title != "" ? true : false }}' style='color: {{ titleColor }}; font-size: {{ titleSize }}rpx;'>{{ title }}</text> <view class='content'> <slot name='content'></slot> </view> <slot name='bottom'></slot> </view> </view>
以上是該組件的模板部分。這部分很簡單,與寫頁面沒什么區別。需要注意的是這里可以使用slot插槽,以上代碼就使用了兩個插槽,分別是模態框的內容部分和底部。因為考慮到擴展性,模態框的內容可能是文字和圖片,所有具體內容需要在使用的時候才能確定。底部也是如此,具體幾個按鈕,以及什么樣式的按鈕都是不能立馬確定下來的。
我們還可以通過內聯樣式來動態的自定義組件的外觀
style='font-size: {{ iconWidth }}rpx; left: {{ iconLeft }}rpx; top: {{ iconTop }}rpx'
最后我們來看下組件的使用與效果。
<e-modal isShow='{{ show1 }}'> <text slot='content' style='color: #666; font-size: 30rpx'>確認退出登錄嗎</text> <e-enhance-view bgColor='#fff' width='600' type='betweenCenter' slot='bottom'> <e-base-button id='cancle' text='取消' theme='fillingAndGradient2' width='285' height='60' textSize='28' color='#FE9036' endColor='#FE4E36' radius='50' catchbuttontap='onModalButtonTap'> </e-base-button> <e-base-button id='ok' text='確認' theme='fillingAndGradient2' width='285' height='60' textSize='28' color='#FE9036' endColor='#FE4E36' radius='50' catchbuttontap='onModalButtonTap'> </e-base-button> </e-enhance-view> </e-modal>
三、結論
總體來看小程序的組件寫起來也是比較簡單的,只要把頁面玩熟了,組件也就水到渠成了。這里只是簡單的總結了組件的使用技巧,如果還沒系統的學習過組件的強烈建議看下官方文檔。關於組件的bug也不是很多,我目前就遇到了一個:在navigator標簽中使用組件會出現無法跳轉的問題。后續遇到bug會進行補充。
四、寫在最后
最后推薦一個由我開發維護的小程序組件庫,里面封裝了開發中常用的組件已經收錄了二十余個,后續還在添加和優化中,希望各位老鐵多多提意見,也可以提交自己的組件。github地址:https://github.com/qq865738120/easyUI