微信小程序學習筆記。

1.小程序起步

(1)點擊https://mp.weixin.qq.com/wxopen/waregister?action=step1根據指引填寫信息和提交相應的資料,就可以擁有自己的小程序賬號。

(2)登陸https://mp.weixin.qq.com,可以在菜單設置-開發設置看到小程序的AppID.小程序AppID相當于小程序平臺的一個身份證。

(3)安裝開發者工具。https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html?t=18101520

2.代碼構成

(1)我們可以通過開發者工具快速創建一個項目。留意里面生成的不同文件類型.

1. .json后綴的JSON配置文件

2. .wxml后綴的WXML模板文件

3. .wxss后綴的WXSS樣式文件

4. .js后綴的JS腳本邏輯文件

(2)JSON配置。

????????在項目的根目錄有一個app.json和project.config.json,此外在page/logs目錄下還有一個logs.json.依次說明它們的用途。

? ? ? ? 1.app.json是小程序的全局配置,包括了小程序的所有頁面路徑、界面表現、網絡超時時間、底部tab等。

????????上圖兩個配置的含義:

????????(1)pages字段:用于描述當前小程序所有頁面路徑,這是為了讓微信客戶端知道當前你的小程序頁面定義在哪個目錄。

????????(2)window字段:定義小程序所有頁面的頂部背景顏色,文字顏色等。

????????2.工具配置project.config.json

????????????通常大家在使用一個工具的時候,都會針對各自的喜好做一些個性化配置。例如界面顏色、編譯配置等等。

????????3.page.json

? ? ????????每個小程序頁面都可以有一個page.json,用于配置一些當前頁面的信息和功能。

(3)WXMl模板。

? ? ? ? WXML就類似于HTML的角色。和HTML非常相似,但有很多地方也不一樣。

? ? ? ? ? ? 1.標簽名字不一樣

? ? ? ? ? ? 2.多了wx:if這樣的屬性以及{{}}這樣的表達式。

(4)WXSS樣式

? ? ? ? 具有css大部分的特性,小程序在WXSS也做了一些擴充和修改。

? ? ? ? ? ? 1.新增尺寸單位。rpx

? ? ? ? ? ? 2.提供了全局樣式和局部樣式。你可以寫一個app.wxss作為全局樣式,會作用與當前小程序的所有頁面,局部樣式? ? ? ? ?page.wxss僅對當前頁面生效

? ? ? ? ? ? 3.WXSS僅支持部分CSS選擇器。

(5)JS交互邏輯

3.小程序的啟動

? ? {

? ? ? ? 'pages':[

? ? ? ? ? ? "pages/index/index",

? ? ? ? ? ? "pages/logs/logs"

? ? ? ? [


? ? 這個配置文件說名小程序項目定義了兩個頁面,分別位于pages/index/index和pages/logs/logs。而寫在pages字段的第一個頁面就是小程序的首頁。(小程序打開的第一個頁面)。小程序在啟動之后,在app.js定義的App實例的onLaunch回調會被執行:

App()?函數用來注冊一個小程序。接受一個?Object?參數,其指定小程序的生命周期回調等。

App() 必須在?app.js?中調用,必須調用且只能調用一次。不然會出現無法預期的后果。

? App(

? ? onLaunch:function(){//小程序啟動之后觸發}

整個小程序只有一個App實例,是全頁面共享的,更多的事件回調參考文檔注冊程序 · 小程序

前臺、后臺定義:當前用戶點擊左上角關閉,或則按了設備Home鍵離開微信,小程序并沒有直接銷毀,而是進入了后臺;當再次進入微信或再次打開小程序,又會從后臺進入前臺。需要注意的是:只有當小程序進入后臺一定時間,或則系統資源占用過高,才會被真正銷毀。

關閉小程序:當用戶從掃一掃、轉發等入口(場景值為1007,1008,1011,1025)進入小程序,且沒有置頂小程序的情況下退出,小程序會被銷毀。

options:

開發者可以在onPageNotFound回調中進行重定向處理,但是必須在回調中同步處理,異步處理無效。

注意:

1.如果開發者沒有添加onPageNotFound監聽,當跳轉頁面不存在時,將推入微信客戶端原生的頁面不存在提示頁面。

2.如果onPageNotFound回調中又重定向到另一個不存在的頁面,將推入微信你客戶端原生的頁面不存在提示頁面,并且不在回調onPageNotFound.

getApp(object)函數可以用來獲取到小程序App實例。注意:

1.不要在定義與App()內的函數中調用getApp(),使用this就可以拿到app實例。

2.通過getApp()獲取實例之后,不要私自調用生命周期函數。

獨立分包

? ? 獨立分包是小程序中一種特殊類型的分包,可以獨立于主包和其他分包運行。從獨立分包中頁面進入小程序時,不需要下載主包。當用戶進入普通分包或主包內頁面是,主包才會被下載。

開發者可以按需將某些具有一定功能獨立性的頁面配置到獨立分包中。當小程序從普通分包頁面啟動時,需要先下載主包;而獨立分包不依賴主包即可運行,可以很大程度上提升分包頁面的啟動速度。一個小程序可以有多個獨立分包。小游戲不支持獨立分包。

開發者通過app.json的subPackages字段中對應的分包配置項中定義independent字段聲明對應分包為獨立分包。

限制:

獨立分包屬于分包的一種。普通分包的所有限制都對獨立分包有效。獨立分包中插件、自定義組件的處理方式同普通分包。此外,使用獨立分包時要注意:

? ? *獨立分包中不能依賴主包和其它分包中的內容。包括js文件、template、wxss、自定義組件、插件等。主包中app.wxss對獨立分包無效,應避免在獨立分包頁面中使用app.wxss中的樣式;

? ? *App只能在主包內定義,獨立分包中不能定義App,會造成無法預期的行為。

? ? *獨立分包中暫時不支持插件。

注意事項:

(1)關于getApp();

? ? ? ? 與普通分包不同,獨立分包運行時,App并不一定被注冊,因此getApp()也不一定可以獲得App對象。?

? ? ? ? ? ? *當用戶從獨立分包頁面啟動小程序時,主包不存在,App也不存在,此時調用getApp()獲取到的是undefind;當用戶進入普通分包或主包內頁面時,主包才會被下載,App才會被注冊。

? ? ? ? ? ? *當用戶是從普通分包或主包內頁面跳轉到獨立分包頁面時,主包已經存在,此時調用getApp()可以獲取到真正的App。

由于這一限制,開發者無法通過App對象實現獨立分包和小程序其它部分的全局變量共享。

為了在獨立分包中滿足這一需求,getApp支持allowDefault參數,在App未定義時返回一個默認實現 。當主包加載,App被注冊時,默認實現中定義的屬性會被覆蓋合并到真正的App中。

? ? (2)關于App生命周期

? ? ? ? ? ? 當從獨立分包啟動小程序時,主包中App的onLaunch和首次onShow會在從獨立分包頁面首次進入主包或其它普通分包頁面時調用。

小程序運行機制

小程序啟動會有兩種情況,一種是冷啟動,一種是熱啟動。假如用戶已經打開過某小程序,此時無需重新啟動,只需要將后臺的小程序切換到前臺,這個過程就是熱啟動;冷啟動指的是用戶首次打開或小程序被微信主動銷毀后再次打開的情況,此時小程序需要重新加載啟動。

更新機制:

? ? 小程序冷啟動時如果發現有新的版本,將會異步下載新版本的代碼包,并同時用客戶端本地的包進行啟動,即新版本的小程序需要下一次冷啟動才會應用上。如果需要馬上應用最新的版本,可以使用wx.getUpdateManagerAPI進行處理。

運行機制:

? ? .小程序沒有重啟概念。

? ? .當小程序進入后臺,客戶端會維持一段時間的運行狀態,超過一定時間后(目前是5分鐘)會被微信主動銷毀。

? ? .當短時間內(5s)連續收到兩次以上收到系統內存警告,會進行小程序的銷毀。

wx.getUpdateManager()返回值是UpdateManager,獲取全局唯一的版本更新管理器,用于管理小程序的更新。

UpdateManager:更新管理器對象。用來管理更新,可以通過wx.getUpdateManager接口獲取實例。

方法:

? ? 1.UpdateManager.applyUpdate()

? ? ? ? 當小程序新版本下載完成后(即onUpdateReady回調),強制小程序重啟并使用新版本。

? ? 2.UpdateManager.onCheckForUpdate(function callback)

? ? ? ? 監聽像微信后臺請求檢查跟新結果的事件。微信你小程序冷啟動時自動檢查更新,不需要由開發者主動觸發。

? ? 3. UpdateManager.onUpdateReady(function callback)

? ? ? ? 艦艇小程序有版本更新事件。客戶端主動觸發下載(無需開發則者觸發),下載成功后回調。

? ? 4.UpdateManager.onUpdateFailed(function callback)

? ? ? ? 監聽小程序更新失敗事件。小程序有新版本,客戶端主動出發下載,下載失敗后回調函數。

注冊頁面

Page(Object)

? ? Page(Object)函數用來注冊一個頁面。接受一個Object類型的參數,其指定頁面的初始數據、生命周期回調、事件處理函數等。

data

? ? data是頁面第一次渲染使用的初始數據。

? ? 頁面加載時,data將會以JSON字符串的形式由邏輯層傳至渲染層,因此data中的數據必須是可以轉成JSON的類型:字符串,數字,布爾值,對象,數組。渲染層可以通過WXML對數據進行綁定。

示例代碼:

生命周期回調函數

? ? onload(Object query)

? ? 頁面加載時觸發。一個頁面只會調用依次,可以在onLoad的參數中獲取打開當前頁面路徑的參數。

? ? onShow():頁面顯示/切入前臺時觸發。

? ? onReady():頁面初次渲染完成時觸發。一個頁面只會調用一次,代表頁面已經準備妥當,可以和視圖層進行交互。

? ? onHide():頁面隱藏/切入后臺時觸發。如navigateTo或底部tab切換到其他頁面,小程序切入后臺等。

? ? onUnload():頁面卸載時觸發。如redirectTo或navigateBack到其他頁面時。

生命周期的觸發以及頁面的路由方式:

? ? 在小程序中所有的頁面的路由全部由框架進行管理。框架以棧的形式維護了當前的所有頁面。當發生路由切換的時候,頁面棧的表現如下:

? ? ? ? 初始化:新頁面入棧。

? ? ? ? 打開新頁面:新頁面入棧。

? ? ? ? 頁面重定向:當前頁面出棧,新頁面入棧。

? ? ? ? 頁面返回:頁面不斷出棧,直到目標返回頁。

? ? ? ? Tab切換:頁面全部出棧,只留下新的tab頁面。

? ? ? ? 重加載:頁面全部出棧,只留下新的頁面。

getCurrentPagess()函數用于獲取當前頁面棧的實例,以數組形式按棧的順序給出,第一個元素為首頁,最后一個元素為當前頁面。

? ? 注意:

? ? ? ? *不要嘗試修改頁面棧,會導致路由以及頁面狀態錯誤。

? ? ? ? *不要在App.onLaunch的時候調用getCurrentPages(),此時page還沒有生成。

路由方式:

? ? ? ? 初始化:小程序打開的第一個頁面,路由當前頁面(),路由后頁面(onload,onShow).

? ? ? ? 打開新頁面:調用wx.navigateTo或使用組件<navigator open-type="navigateTo"/> 路由當前頁面(onHide)路由后頁面(onLoad,onShow)

? ? ? ? 頁面重定向:調用API wx.redirectTo或使用組件<navigator open-type="redirectTo"/>路由前頁面(onUnload),路由后頁面(onLoad,onShow)

? ? ? ? 頁面返回:調用API wx.navigateBack或使用組件<navigator open-type="navigateBack"/>路由前頁面(onUnload)路由后頁面(onShow)

? ? ? ? tab切換:調用API wx.switchTab或使用組件<navigator open-type="switchTab">路由前頁面(路由后頁面分情況:

? ? ? ? 重啟動:調用API wx.reLaunch或使用組件<navigator open-type="reLaunch"/>路由前頁面(onUnload)路由后頁面(onLoad,onShow)

tab切換對應的生命周期(以A、B頁面為Tabbar,C是從A頁面打開的頁面,D頁面是從C頁面打開的頁面):

? ? ? ? *navigateTo,redirectTo只能打開非TabBar頁面。

? ? ? ? *switchTab只能打開tabbar頁面。

? ? ? ? *relaunch可以打開任意頁面。

? ? ? ? *頁面底部的tabBar由頁面決定,即只要定義為tabBar的頁面,底部都有tabbar.

? ? ? ? *調用頁面路由帶的參數可以在目標頁面的onload中獲取。

(1)wx.navigateTo(object object)保留當前頁面,跳轉到應用內的某個頁面,但是不能跳到tabbar頁面。

? ? (2)wx.navigateBack(object object)關閉當前頁面,返回上一頁面或多級頁面。可以通過getCurrentPages()獲取當前頁面棧,決定需要返回基層。

? ? (3)wx.switchTab(object object)跳轉到tabBar頁面,并關閉其他所有非tabBar頁面。

? ? (4)wx.reLaunch(Object object)關閉所有頁面,打開到應用內的某個頁面.

頁面事件處理函數:

? ? onPullDownRefresh():

? ? ? ? 監聽用戶下拉刷新事件。

? ? ? ? ? ? *需要在app.json的window選項中或頁面配置中開啟enablePullDownRefresh.

? ? ? ? ? ? *可以通過wx.startPullDownRefresh觸發下拉刷新,調用后觸發下拉刷新動畫,效果與用戶手動下拉刷新一致。

? ? ? ? ? ? *當處理完數據刷新后,wx.stopPullDwonRefresh可以停止當前頁面的下拉刷新。

? ? onReachBottom()

? ? ? ? 監聽用戶上拉觸底事件。

? ? ? ? ? ? *可以在app.json的window選項中或頁面配置中設置觸發距離onReachBottomDistance。

? ? ? ? ? ? *在出發距離內滑動期間,本事件只會觸發一次。

? ? onPageScroll(Object):

? ? ? ? 監聽用戶滑動頁面事件。

? ? ? ? ? ? Object參數說明:scrollTop 類型:Number,頁面在垂直方向已滾動的距離(單位px)。

? ? onShareAppMessage(Object)

? ? ? ? 監聽用戶點擊頁面內轉發按鈕或<button>組件open-type="share"或右上角菜單轉發按鈕的行為,并且自定義轉發內容。

? ? ? ? 注意:只有定義了此事件處理函數,右上角菜單才會顯示轉發按鈕。

? ? ? ? ? ? 參數? ? ? ? ? ? ? ? ? ? ? ? ? 類型? ? ? ? ? ? ? 說明

? ? ? ? ? ? from? ? ? ? ? ? ? ? ? ? ? ? ?String? ? ? ? ? ? ?button:頁面內轉發按鈕;,menu右上角轉發菜單。

? ? ? ? ? ? target? ? ? ? ? ? ? ? ? ? ? ?Object? ? ? ? ? ? 如果from值是button,則target是觸發這次轉發事件的button,否則為undefined。

? ? ? ? ? ? webViewUrl? ? ? ? ? ? ?String? ? ? ? ? ? ? 頁面中包含<web-view>組件時,返回當前<web-view>的url

? ? ? ? 此事件需要一個return一個Object,用于自定義轉發內容,返回內容如下:

? ? ? ? ? ? 字段? ? ? ? ? ? ? ? ? ?說明? ? ? ? ? ? ? ? ? ? ? ?默認值

? ? ? ? ? ? title? ? ? ? ? ? ? ? ? ? ?轉發標題? ? ? ? ? ? ? ?當前小程序名稱

? ? ? ? ? ? path? ? ? ? ? ? ? ? ? ? 轉發路徑? ? ? ? ? ? ? ?當前頁面path,必須是以/開頭的完整路徑

? ? ? ? ? ? imageUrl? ? ? ? ? ? ?自定義圖片路徑? ? ?使用默認截圖


? ? 組件事件處理函數

? ? ? ? page中還可以定義組件事件處理函數。在渲染層的組件中加入事件綁定,當事件被觸發時,就會執行Page中定義的事件處理函數。

? ? Page.route

? ? ? ? 到當前頁面的路徑,類型為string

? ? ? ? Page.prototype.setData(Object data,Function callback):setData函數用于將數據從邏輯層發送到視圖層(異步),同時改變對應的this.data的值。?

? ? ? ? 字段? ? ? ? ? ? ? ? ? ? ? 類型? ? ? ? ? ? ? ? ? 必填? ? ? ? ? ? ? ? 描述? ? ? ? ? ? ? ? ? ? ?

? ? ? ? data? ? ? ? ? ? ? ? ? ? ? ?Obejct? ? ? ? ? ? ? ?是? ? ? ? ? ? ? ? ? ?這次要改變的數據

? ? ? ? callBack? ? ? ? ? ? ? ? ?Function? ? ? ? ? ?否? ? ? ? ? ? ? ? ? ?setData引起的界面更新渲染完畢后的回調函數

objec以key:value的形式表示,將this.data中key對應的值改變為value。

其中key可以以數據路徑的形式給出,支持改變數組中的某一項或對象的某個屬性,如arry[2].message,a,b,c,d,并且不需要在this.data中預先定義。

注意:

? ? 1.直接修改this.data而不調用this.setData是無法改變頁面的狀態的,還會造成數據不一致。

? ? 2.僅支持設置可JSON化的數據。

? ? 3.單次設置的數據不能超過1024kb,請盡量避免一次設置過多的數據。

? ? 4.請不要把data中任何一項的value設為undefined,否則這一項將不被設置并可能遺留一些潛在問題。

視圖層

WXML

WXML是框架設計的一套標簽語言,結合基礎組件、系統事件,可以構建出頁面的結構。

自定義組件

1.創建自定義組件

? ? 類似于頁面,一個自定義組件由json,wxml,wxss,js4個文件組成。要編寫一個自定義組件,首先需要在json文件中進行自定義組件聲明(將component字段設為true可這一組文件設為自定義組件):

? ? {

? ? ? ? "component":true

????}

同時,還要在wxml文件中編寫組件模板,在wxss文件中加入組件樣式,它們的寫法與頁面的寫法類似。具體細節和注意事項參見組建模板和樣式。

注意:在組件wxss中不應使用ID選擇器、屬性選擇器和標簽名選擇器。

? ? ? ? 在自定義組件js文件中,需要使用Component()來注冊組件,并提供組件的屬性定義、內部數據和自定義方法。

? ? ? ? 組件的屬性值和內部數據將被用于組件WXML的渲染,其中,屬性值是可由組件外部傳入的。

使用已注冊的自定義組件前,首先要在頁面的json文件中進行引用聲明。此時需要提供每個自定義組件的標簽名和對應的自定義組件路徑:

Component構造器

? ? Component構造器可用于定義組件,調用Component構造器時可以指定組件的屬性、數據、方法等。

? ? 定義段? ? ? ? ? ? ? 類型? ? ? ? ? ? 是否必填? ? ? ?描述

? ? properties? ? ? ? ?Object Map 否? ? ? ? ? ? ? ? ? 組件的對外屬性,是屬性名到屬性設置的映射表,屬性設置中可包含三個字段,type表示屬性類型、value表示屬性初始值、observer表示屬性值被更改時的響應函數。

? ? data? ? ? ? ? ? ? ? ? ? Object? ? ? ? 否? ? ? ? ? ? ? ? ?組件的內部數據,和properties一同用于組件的模板渲染

? ? methods? ? ? ? ? ? ?Object? ? ? ?否? ? ? ? ? ? ? ? ? 組件的方法,包含事件響應函數和任意的自定義方法,關于事件的響應函數的使用,參見組件事件

? ? behaviors? ? ? ? ? ?String Array? 否? ? ? ? ? ? ? ?類似于mixins和traits的組件間代碼復用機制,參見behaciors

? ? created? ? ? ? ? ? ? ?Function? ? 否? ? ? ? ? ? ? ? ? 組件生命周期函數,在組件實例進入頁面節點樹時執行,注意此時不能調用setData

? ? attached? ? ? ? ? ? ?Function? ? ?否? ? ? ? ? ? ? ? ?組件生命周期函數,在組件實例進入頁面節點樹時執行。

? ? ready? ? ? ? ? ? ? ? ? Function? ? ?否? ? ? ? ? ? ? ? ?組件生命周期函數,在組件布局完成后執行,此時可以獲取節點信息。

? ? moved? ? ? ? ? ? ? ? Function? ? ?否? ? ? ? ? ? ? ? ?組件生命周期函數,在組件實例被移動到節點樹另一個位置時執行。

? ? detached? ? ? ? ? ? Function? ? ?否? ? ? ? ? ? ? ? ?組件生命周期函數,在組件實例被從頁面節點樹移除時執行。

? ? relations? ? ? ? ? ? ?Object? ? ? ? ?否? ? ? ? ? ? ? ? ?組件間關系定義,參見組件間關系

? ? externalClasses String Array 否? ? ? ? ? ? ? ? 組件接受的外部樣式類,參見外部樣式類。

? ? options? ? ? ? ? ? ? ?Object Map? 否? ? ? ? ? ? ? ? 一些選項(文檔中介紹相關特性時會涉及具體的選項設置,這里暫不列舉)

? ? lifetimes? ? ? ? ? ? ?Object? ? ? ? ? 否? ? ? ? ? ? ? ? 組件生命周期聲明對象,組件的生命周期:created、attached、ready、moved、detached將收歸到lifetimes字段內進行聲明,原有聲明方式仍舊有效,如同時存在兩種聲明方式,則lifetimes字段內聲明方式優先級最高

? ? pageLifetimes? ? Object? ? ? ? ? 否? ? ? ? ? ? ? ? 組件所在頁面的生命周期聲明對象,目前僅支持頁面的show和hide兩個生命周期

? ? definitionFilter? ? Function? ? ? 否? ? ? ? ? ? ? ? ?定義段過濾器,用于自定義組件擴展,參見自定義組件擴展。

生成的組件實例可以在組件的方法、生命周期函數和屬性observer中通過this訪問。組件包含一些通用屬性和方法。

屬性名? ? ? ? ? ? ? ? ? ? ? ? 類型? ? ? ? ? ? ? ? ? ? ?描述

is? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String? ? ? ? ? ? ? ? ? ?組件的文件路徑

id? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String? ? ? ? ? ? ? ? ? ?組件節點id

dataset? ? ? ? ? ? ? ? ? ? ? ?String? ? ? ? ? ? ? ? ? ?節點 dataset

data? ? ? ? ? ? ? ? ? ? ? ? ? ? Object? ? ? ? ? ? ? ? ? 組件數據,包括內部數據和屬性值

properties? ? ? ? ? ? ? ? ? ?Object? ? ? ? ? ? ? ? ? 組件數據,包括內部數據和屬性值(與data一致)

方法名? ? ? ? ? ? ? ? ? ? ? ? 參數? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?描述

setData? ? ? ? ? ? ? ? ? ? ? Object newData? ? ? ? ? ? ? 設置data并執行視圖層渲染

hasBehavior? ? ? ? ? ? ? Object behavior? ? ? ? ? ? ? ?檢查組件是否有behavior(檢查時會遞歸檢查被直接或間接引入的所有behavior)

triggerEvent? ? ? ? ? ? ? ?String name,Object detail,Object options 觸發事件,參見組件事件

createSelectorQuery? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 創建一個SelectorQuery對象,選擇器選取范圍為這個組件實例內。

createIntersectionObserver? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 創建一個IntersectionObserver對象,選擇器選取范圍為這個組件實例內

selectComponent? ? ? ?String selector? ? ? ? ? ? ? ? ?使用選擇器選擇組件實例節點,返回匹配到的第一個組件實例對象(會被?wx://component-export?影響)

selectAllComponents? String? ? ? ? ? ? ? ? ? ? ? ? ? ? ? selector使用選擇器選擇組件實例節點,返回匹配到的全部組件實例對象組成的數組

getRelationNodes? ? ? ?String?relationKey? ? ? ? ? ? 獲取這個關系所對應的所有關聯節點,參見?組件間關系

簡單的組件應用demo:

組件wxml
組件js
引入組件
獲取組件傳過來的值

組件間通信

組件間通信

組件間的基本通信方式有以下幾種:

? ? ? ? *WXML數據綁定:用于父組件向子組件的指定屬性設置數據,僅能設置JSON兼容數據。

? ? ? ? *事件:用于子組件向父組件傳遞數據,可以傳遞任意數據。

? ? ? ? *如果以上兩種方式不能滿足需要,父組件還可以通過this.selectComponent方式獲取子組件實例對象,這樣就可以直接訪問組件的任意方法和數據。

監聽事件

? ? 事件系統是組件間通信的主要方式之一。自定義組件可以觸發任意的事件,引用組件的頁面可以監聽這些事件。關于事件的基本概念和用法,參見事件。

? ? 監聽自定義組件事件的方法與監聽基礎組件事件的方法完全一致:

? ??觸發事件

? ? ? ? ? ? 自定義組件觸發事件時,需要使用triggerEvent方法,指定事件名、detail對象和事件選項:

? ? ? ? ? ? ? 觸發事件的選項包括:

? ? ? ? ? ? ? ? bubbles? ? ? ? ? ?Boolean? ? ? ? ?不是必填? ? ? ? ? ? 默認值false? ? ? ? ? ? ? ?事件是否冒泡

? ? ? ? ? ? ? ? composed? ? ? ?Boolean? ? ? ? ? 不是必填? ? ? ? ? ?默認值false? ? ? ? ? ? ? ?事件是否可以穿越組件邊界,為false時,事件將只能在引用組件的節點樹上觸發,不進入其他組件內部。

? ? ? ? ? ? ? ? captruePhase? Boolean? ? ? ? ?不是必填? ? ? ? ? ? 默認值false? ? ? ? ? ? ? ? 事件是否擁有捕獲階段。

組建模板
my-componet組件綁定ontap事件
引入組件的js定義事件(接收triggerEvent事件)

behaviors

? ??定義和使用 behaviors

? ? ? ? behaviors是用于組件代碼共享的特性,類似于一些編程語言中的mixins或traits。

? ? ? ? 每個behavior可以包含一組屬性、數據、生命周期函數和方法,組建引用它時,他的屬性、數據和方法都會被合并到組件中,生命周期也會對應時機被調用。每個組件可以引用多個behavior。behavior也可以引用其它behavior。

? ? ? ? behavior需要使用Behavior()構造器定義。

? ? ? ? 組件引用時,在behaviors定義段中將它們逐個列出即可。

? ? ? ? ? ? 在上例中,my-component組件定義中加入了my-behavior,而my-behavior中包含有myBehaviorProperty屬性、?myBehaviorData數據字段、?myBehaviorMethod?方法和一個?attached?生命周期函數。這將使得my-component中最終包含myBehaviorProperty?、?myProperty?兩個屬性,myBehaviorData?、?myData?兩個數據字段和?myBehaviorMethod?、?myMethod?兩個方法。當組件觸發attached生命周期時,會依次觸發my-behavior?中的?attached?生命周期函數和?my-component?中的?attached?生命周期函數。

? ? ? ?字段的覆蓋和組合規則

? ? ? ? ? ? 組件和它引用的behavior中可以包含同名字段,對這些字段的處理方法如下:

? ? ? ? ? ? ? ? *如果有同名的屬性或方法,組件本身的屬性或方法會覆蓋behavior中的屬性或方法,如果引用了多個behavior,在定義段中靠后behavior中的屬性和方法會覆蓋靠前的屬性或方法;

? ? ? ? ? ? ? ? *如果有同名的數據字段,如果數據是對象類型,會進行對象合并,如果是非對象類型則會進行相互覆蓋;

? ? ? ? ? ? ? ? *生命周期函數不會相互覆蓋,而是在對應觸發時機逐個調用。如果同一個behavior被一個組件多次引用,他定義的生命周期函數只會被執行依次。


? ? ? ? ?內置behaviors

? ? ? ? ? ? ? ? 自定義組件可以通過引用內置的behavior來獲取內置組件的一些行為。

? ? ? ? ? ? ? ? 在上例中,wx://form-field?代表一個內置?behavior,它使得這個自定義組件有類似于表單控件的行為。

? ? ? ? ? ? ? ? 內置behavior往往會為組件添加一些屬性。在沒有特殊說明時,組件可以覆蓋這些屬性來改變它的type或添加observer。

? ? ? ? ? ? 組件中slot使用

? ? ? ? ? ? ? ? ? ? 如果引入組件的wxml中,想在組件中寫入其它的東西,需要在組件中寫入一個slot插槽,這樣才會正常顯示。

? ? ? ? ? ? ? ? ? ? ? ? 使用多個slot,在正常情況下,一個組件只有一個slot,但有時候我們的自定義組件可能不止使用一個slot,需要使用多個slot時,可以在組件js中聲明啟用。

? ? ? ? ? ? ? ? ? ? ? ? 1.在js中聲明

? ? ? ? ? ? ? ? ? ? ? ? 2.在組件中使用多個slot,以不同的name來區分:

? ? ? ? ? ? ? ? ? ? ? ? 3。使用時,用slot屬性來將節點插入到不同的slot上。

組件間關系

? ? ? ? 定義和使用組件間的關系

? ? ? ? ? ? ? ? 有時需要實現這樣的組件:

? ? ? ? ? ? 這個例子中,custom-ul和custom-li都是自定義組件,他們有相互間的關系,相互間的通信往往比較復雜。此時在組件定義時加入relations定義段,可以解決這樣的問題。示例:

? ? ? ? 1.引入組件的wxml:??

引入的父組件下所有li都會顯示到slot里面,沒有slot則會不顯示

? ? ? ? ?2.custom-ul組件:父組件

slot插槽為了顯示custom-li

? ? ? ? 3.custom-li組件:子組件

與custom-ul父子關系

? ? ? ? ?4.在子組件和父組件中的js文件中Component中定義relations,并表明父子或則祖先關系。?

custom-li子組件
custom-ul父組件

? ??關聯一類組件

? ? ? ? ? 有時需要關聯的是一類組件:

引入3個組件
index.json
form組件wxml
祖先組件,custom-form組件想要關聯custom-input和custom-submit兩個組件。此時如果這兩個組件都有同一個behavior:則在?relations?關系定義中,可使用這個behavior來代替組件路徑作為關聯的目標節點:
input組件
submit組件

抽象節點

? ??????在組件中使用抽象節點

? ? ? ? ? ? 有時,自定義組件模板中的一些節點,其對應的自定義組件不是由自定義組件本身確定的,而是自定義組件調用者確定的。這時可以把這個節點聲明為‘抽象節點’。

? ? ? ? ? ?例如,我們現在來實現一個選項框組件,(selectable-group)組件,它其中可以放置單選框(custom-radio)或者復選框(custom-checkbox)。實例鏈接:https://github.com/WangShuXian6/miniprogram-demo/tree/develop/abstract-com

自定義組件擴展

? ? 通過例子可以發現,自定義組件的擴展其實就是提供了修改自定義組件定義段的能力,上述例子中就是修改了自定義組件中的data定義段的內容。

? ? Behavior()構造器提供了新的定義段definitionFilter,用于支持自定義組件擴展。definitionFilter是一個函數,在被調用時會注入兩個參數,第一個參數是使用該behavior的component/behavior的定義對象,第二個參數是該behavior所使用的behavior的definitionFilter函數列表。

上述代碼中聲明了1個自定義組件和3個behavior,每個behavior都使用了definitionFilter定義段。那么按照聲明的順序會有如下事情發生。

1.當進行behavior2的聲明時就會調用behavior3的definitionFilter函數,其中defFields參數是behavior2的定義段,definiyionFilterArr參數即為空數組,因為behavior3沒有使用其它的behavior。

2.當進行behavior1的聲明時就會調用behavior2的definitionFilter函數,其中defFields參數是behavior1的定義段,definitionFilterArrr參數是一個長度為1的數組,definitionFilterArr[0]即為behavior3的definitionFilter函數,因為behavior2使用了behavior3.用戶在此處可以自行決定在進行behavior1的聲明時要不要調用behavior3的definitionFilter函數,如果需要調用,在此處補充代碼definitionFilterArr[0](defFields)?即可,definitionFilterArr?參數會由基礎庫補充傳入。

3.同理,在進行 component 的聲明時就會調用 behavior1 的?definitionFilter?函數。

下面利用擴展簡單實現自定義組件的計算屬性功能:

// behavior.js

? ? 在組件中使用:

實現原理很簡單,對已有的 setData 進行二次封裝,在每次 setData 的時候計算出 computed 里各字段的值,然后設到 data 中,已達到計算屬性的效果。

開發第三方自定義組件

? ? 開發一個開源的自定義組件包括給他人使用,首先需要明確他人是要如何使用這個包的,如果只是拷貝小程序目錄下直接使用的餓話,就可以跳過此文檔。此文檔中后續內容是以npm管理自定義組件的前提下進行說明的。

? ? 在開發之前,要求開發者具有基礎的node.js和npm相關的知識,同時需要準備好支持npm功能的開發者工具,點此下載。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容