從小程式基礎庫版本 1.6.3 開始,小程式支援簡潔的元件化程式設計。所有自定義元件相關特性都需要基礎庫版本 1.6.3 或更高。元件化程式設計的精髓是高内聚低耦合的複用機制,這對任意一家平台開發商而言都是降低成本和保證高品質營運的關鍵。
小程式元件化程式設計有什麼特點
◐ 封裝粒度小于頁面,是特定業務面(Business Aspects)的封裝器
一個自定義元件由 json wxml wxss js 4個檔案組成,分别代表聲明、模闆、樣式和邏輯,這點和頁面相同,元件聲明的格式如下:
json檔案
{
"component": true
}
wxml檔案
<!-- 這是自定義元件的内部 WXML 結構 -->
<view class="inner">
{{innerText}}
</view>
<slot></slot>
vue玩家這裡很熟悉吧,有一個分發槽,幹什麼的我就不用說了[大笑]
wxss檔案
/* 這裡的樣式隻應用于這個自定義元件 */
.inner {
color: red;
}
js檔案
//構造器
Component({
properties: {
// 這裡定義了 innerText 屬性,屬性值可以在元件使用時指定
innerText: {
type: String,
value: 'default value',
}
},
// 私有資料,可用于模闆渲染
data: {
// 這裡是一些元件内部資料
someData: {}
},
methods: {
// 這裡是一個自定義方法
customMethod: function(){}
},
//公用的代碼段,面向面的程式設計,比如加載、銷毀時的log等
behaviors: [],
//元件生命周期
lifetimes:{
},
//元件所在頁面生命周期
pageLifetimes:{
}
})
引用元件時,需在引用頁面或元件的json檔案中聲明
{
"usingComponents": {
"component-tag-name": "path/to/the/custom/component"
}
}
usingComponents會觸發Components構造器的調用,是以,我們如果把頁面也作為特殊的元件,則可以通過引入usingComponents和Components的方式使頁面元件化,這樣會潛在的帶來很多好處,比如:如通路頁面 /pages/index/index?paramA=123¶mB=xyz ,如果聲明有屬性 paramA 或 paramB ,則它們會被指派為 123 或 xyz,如此等等吧。
◐ 元件屬性、資料的使用和通訊
元件化方法是自治政策的應用,是以,元件機制應解決資料傳入、自身渲染和上下文資料通訊的問題,在微信小程式裡,其分别的實作機制如下:
【1】資料傳遞和Vue機制類似,父傳子通過properties,子傳父通過子元件觸發事件來完成,觸發事件須使用triggerEvent 方法,指定事件名、detail對象和事件選項,如下例:
Component({
properties: {},
methods: {
onTap: function(){
var myEventDetail = {} // detail對象,提供給事件監聽函數
var myEventOption = {} // 觸發事件的選項
this.triggerEvent('myevent', myEventDetail, myEventOption)
}
}
})
除了上述兩種情況,還有父元件還可以通過 this.selectComponent 方法擷取子元件執行個體對象,這樣就可以直接通路元件的任意資料和方法,愛怎麼玩怎麼玩。但這裡要注意,調用時需要傳入一個比對選擇器 selector,如:this.selectComponent(".my-component")。
【2】元件的生命周期,指的是元件自身的一些函數,這些函數在特殊的時間點或遇到一些特殊的架構事件時被自動觸發。其中,最重要的周期事件是 created、attached、detached ,包含一個元件執行個體生命流程的最主要時間點。元件的生命周期對應事件寫在元件構造器的lifetimes對象裡。
Component({
lifetimes: {
attached: function() {
// 在元件執行個體進入頁面節點樹時執行
},
detached: function() {
// 在元件執行個體被從頁面節點樹移除時執行
},
},
// 以下是舊式的定義方式,可以保持對 <2.2.3 版本基礎庫的相容
attached: function() {
// 在元件執行個體進入頁面節點樹時執行
},
detached: function() {
// 在元件執行個體被從頁面節點樹移除時執行
},
// ...
})
元件關聯頁面的跟蹤和監控寫在pageLifetimes裡。
Component({
pageLifetimes: {
show: function() {
// 頁面被展示
},
hide: function() {
// 頁面被隐藏
},
resize: function(size) {
// 頁面尺寸變化
}
}
})
元件的資料監聽機制
元件通過 observers對象提供vue中類似watch的功能以實作資料監聽,在MVVM模型中,資料的變化驅動事件産生必須有資料監聽機制才行,這裡不廢話了,上個例子。
Component({
observers: {
'some.subfield': function(subfield) {
// 使用 setData 設定 this.data.some.subfield 時觸發
// (除此以外,使用 setData 設定 this.data.some 也會觸發)
subfield === this.data.some.subfield
},
'arr[12]': function(arr12) {
// 使用 setData 設定 this.data.arr[12] 時觸發
// (除此以外,使用 setData 設定 this.data.arr 也會觸發)
arr12 === this.data.arr[12]
},
'numberA, numberB': function(numberA, numberB) {
// 在 numberA 或者 numberB 被設定時,執行這個函數
this.setData({
sum: numberA + numberB
})
}
}
})
小程式開發的最佳實踐
◐ 子產品化
可以将一些公共的代碼抽離成為一個單獨的 js 檔案,作為一個子產品。子產品隻有通過 module.exports 或者 exports 才能對外暴露接口。
// common.js
function sayHello(name) {
console.log(`Hello ${name} !`)
}
function sayGoodbye(name) {
console.log(`Goodbye ${name} !`)
}
module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye
在需要使用這些子產品的檔案中,使用 require 将公共代碼引入
var common = require('common.js')
Page({
helloMINA: function() {
common.sayHello('MINA')
},
goodbyeMINA: function() {
common.sayGoodbye('MINA')
}
})
◐ 避免異常
出現 JavaScript 異常、網絡異常可能導緻程式的互動無法進行下去,我們應當追求異常對正常互動的幹擾,保證程式的高魯棒性和高可用性。
◐ 不使用廢棄接口
使用即将廢棄或已廢棄接口,可能導緻小程式運作不正常。一般而言,接口不會立即去掉,但保險起見,建議不要使用,避免後續小程式突然運作異常。不要使用任何文檔中提示廢棄的接口。
◐ 避免setData資料備援
setData操作會引起架構處理一些渲染界面相關的工作,一個未綁定的變量意味着與界面渲染無關,傳入setData會造成不必要的性能消耗。是以,setData傳入的所有資料在模闆渲染中都要有相關依賴。
◐ 最低基礎庫版本
當使用的元件/API 的支援版本大于配置的線上最低基礎庫版本時,可能導緻相應功能不可用。開發者可通過調整最低基礎庫版本或在代碼上相容的方式解決該問題。不要存在使用的元件/API 的支援版本大于配置的線上最低基礎庫版本的情況。
◐ 移除不可通路到的頁面
小程式的包大小會影響加載時間,應該盡量控制包體積大小,避免将不會被使用的檔案打包進去。存在通路不到的頁面被打包到小程式中
◐ 及時回收定時器
定時器是全局的,并不是跟頁面綁定的,當小程式從一個頁面路由到另一個頁面之後,前一個頁面定時器應注意手動回收。是以,確定所有定時器的回調執行時,所在的頁面都與設定定時器的頁面一緻。
結合前面一片的小程式開發,現在相信馬上可以開始幹活了,小程式是一個相對完整的封閉開發環境,和VUE、HBuilderX的uni-app等還是存在差異的,使用時多摸索多學習,相信一定會開發出令人眼前一亮的小程式。最後,還是那句話,打賞打賞。
#頭條創作挑戰賽#