筆者由於工作需要,曾經參加過一個微信小程序同 SAP 系統集成的項目,因此從零開始學習了微信小程序的開發知識。這裏通過系列文章把自己所學分享出來,希望對相關學習者有所幫助。
本教程前面兩篇文章:
- 微信小程序開發系列 (一) :開發環境搭建和微信小程序的視圖設計與開發
- 微信小程序開發系列 (二) :微信小程序的單步調試和控制器實現步驟概述
通過本教程前面兩篇文章的介紹,大家對微信小程序的視圖和控制器,以及微信調試器的用法已經有了一個最基本的認識了。在這個基礎上,讓我們進一步學習微信小程序控制器,掌握在小程序控制器中響應用户輸入的方法。
這個例子很簡單,在微信小程序的視圖 index.wxml 裏,我定義了一個按鈕,和一個文本元素。
<button bindtap="jerry_increase"> 點我加1 </button>
<text class="user-motto">{{counter}}</text>
文本元素綁定到小程序數據模型的 counter 字段上,是一個計數器。按鈕綁定了一個事件處理函數 jerry_increase.
每點擊一次按鈕,微信小程序 UI 上的計數器加一。
為此,首先需要在控制器 index.js 的 data 數據模型裏增添一個 counter 字段。
然後實現 button 的 bindtap 綁定的函數 jerry_increase.
可以看到這個事件處理函數有一個輸入參數 e:
當事件處理函數被調用時,這個輸入參數 e 是微信框架自動傳入到事件處理函數的。通過微信開發者工具的調試器可以看到這個參數 e 的明細:tap 事件發生的 X 和 Y 座標,以及事件類型 tap.
我們如果從當前控制器事件處理函數執行棧向外觀察,發現它的前一層,即微信框架層的處理邏輯裏,在調用事件處理函數前後分別取兩個當前的時間戳。如果時間戳之差大於 1000 毫秒,會執行第 30365 行的 Reporter.slowReport.
由此我們看出,微信希望開發者實現的事件處理函數要儘可能高效,執行時間不能超過 1 秒。在手機使用場景裏,1 秒的等待時間對於最終用户來説不算短了。
另一個值得一提的知識點是,如果直接用 JavaScript 修改數據模型的值,則 UI 不會有任何變化。
下面是錯誤的做法:
jerry_increase: function(e){
this.data.counter = this.data.counter + 1;
},
下面是正確的做法:
jerry_increase: function(e){
this.setData({
counter: this.data.counter + 1
});
},
我們可以通過單步調試正確的做法來理會其中的奧妙:
可以看到 this.setData 裏面會調用微信框架的 c.default.emit 函數,把最新的數據通過 emit 函數投遞出去。
繼續查看 emit 的實現,可以發現 emit 又調用了微信工具類 wx 的方法:invokeWebviewMethod。
從 WAService.js 的內部實現,我們能發現其實微信小程序在手機上的執行實際是運行在 WebView 裏的。
一旦 WeixinJSBridge.publish.apply(WeixinJSBridge, e) 這一行代碼執行完畢,UI 上的計數器才被刷新。
本文介紹瞭如果在微信小程序裏編寫 JavaScript 來響應 button 的點擊事件。
本系列的下一篇文章會介紹微信小程序的 button 組件提供的一些微信原生功能,比如獲取當前用户信息等強大功能的用法。
微信框架 API 的調用
通過迄今為止的介紹,大家對微信小程序的視圖和控制器,微信調試器,以及如何在微信控制器裏編寫 JavaScript 函數來響應微信小程序的用户事件,已經有了一個最基本的認識了。
我們現在來開發一個微信小程序的實際例子,進一步鞏固以前學到的知識。
這個例子的效果如下:在微信小程序上顯示一個按鈕:獲取頭像暱稱。
點擊之後,微信小程序會自動通過微信框架提供的 API 把當前點擊這個按鈕的微信用户的明細,比如暱稱,頭像,所在省份,城市等信息取回來,並且顯示在小程序頁面上, 如下圖所示。
視圖設計:
<view class="userinfo">
<button open-type="getUserInfo" bindgetuserinfo="jerry_getUserInfo"> 獲取頭像暱稱 </button>
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
<text class="userinfo-nickname">{{userInfo.city}}</text>
<text class="userinfo-nickname">{{userInfo.country}}</text>
<text class="userinfo-nickname">{{userInfo.province}}</text>
</view>
這個視圖裏一共有 6 個 UI 元素,其中 1 個 button 元素,1 個 image 元素和 4 個 text 元素。
button 元素負責響應用户點擊事件,調用微信框架的 API 讀取用户明細。
1 個 image 元素負責顯示點擊該按鈕的微信用户頭像,剩下的 4 個 text 元素顯示微信用户的明細。後 5 個UI元素的綁定路徑均為 userInfo,而 userInfo 的數據是點了 button 後通過調用微信 API 讀取的。
這個 userInfo 是我們在控制器 index.js 裏定義的數據模型:
Page({
data: {
userInfo: {}
}
});
我們回過頭來看本文這個小程序最重要的 button 元素,它有兩個屬性:
- open-type="getUserInfo" :説明該 button 點擊之後,自動調用微信框架的 API
getUserInfo; - bindgetuserinfo="jerry_getUserInfo":指定了一個回調函數的名稱,該回調函數在我們的控制器
index.js裏實現。
當微信框架的 API 調用成功取回微信用户明細後,會將微信用户明細作為輸入參數,調用我們寫的這個回調函數。
jerry_getUserInfo: function(e) {
app.globalData.userInfo = e.detail.userInfo
this.setData({
userInfo: e.detail.userInfo
});
}
在小程序能夠訪問的上下文裏,有一個全局變量 wx,裏面包含了所有微信框架暴露出來的API:
在微信小程序官網上有關於這個 wx的所有成員説明:
我們再試試另外一個 API:getSystemInfo.
首先在小程序視圖裏定義一個按鈕,綁定一個 JavaScript 函數 jerry_systeminfo, 用於觸發 getSystemInfo:
<button bindtap = "jerry_systeminfo"> 獲取系統信息 </button>
然後定義七個 UI 元素,用於顯示 getSystemInfo 的返回結果。
<text class="userinfo-nickname">{{systeminfo.model}}</text>
<text class="userinfo-nickname">{{systeminfo.pixelRatio}}</text>
<text class="userinfo-nickname">{{systeminfo.windowWidth}}</text>
<text class="userinfo-nickname">{{systeminfo.windowHeight}}</text>
<text class="userinfo-nickname">{{systeminfo.language}}</text>
<text class="userinfo-nickname">{{systeminfo.version}}</text>
<text class="userinfo-nickname">{{systeminfo.platform}}</text>
wx.getSystemInfo 返回的結果作為一個輸入參數,自動傳入到我們定義的 success 回調函數裏,然後再用 setData 設置到視圖的數據結構裏。
jerry_systeminfo: function(){
var that = this;
wx.getSystemInfo({
success: function (res) {
var systeminfo = {};
systeminfo.model = res.model;
systeminfo.pixelRatio = res.pixelRatio;
systeminfo.windowWidth = res.windowWidth;
systeminfo.windowHeight = res.windowHeight;
systeminfo.language = res.language;
systeminfo.version = res.version;
systeminfo.platform = res.platform;
try {
that.setData({
systeminfo: systeminfo
});
}
catch(e){
console.log(e);
}
}
})
},
最後我在我的 Android 三星手機上點擊“獲取系統信息”之後,就顯示出了我三星手機的型號SM-C7010 等詳細信息。
總結
本教程首先介紹了微信小程序控制器裏如何響應用户點擊事件,然後通過一個實際的如何獲取當前用户微信暱稱和手機信號的例子,介紹了微信小程序如何消費微信平台 API 的方法。
本教程前面兩篇文章:
- 微信小程序開發系列 (一) :開發環境搭建和微信小程序的視圖設計與開發
- 微信小程序開發系列 (二) :微信小程序的單步調試和控制器實現步驟概述