邏輯層
邏輯層猜年,是事務邏輯處理的地方。對于微信小程序而言疾忍,邏輯層就是所有.js腳本文件的集合乔外。微信小程序在邏輯層將數(shù)據(jù)進行處理后發(fā)送給視圖層,同時接受視圖層的事件反饋一罩。
在JavaScript的基礎上杨幼,微信團隊做了一些適當?shù)匦薷模饕男薷陌ǎ?br>
■增加App和Page方法聂渊,進行程序和頁面的注冊差购。
■增加getApp和getCurrentPage方法归榕,分別用于獲取App實例和當前頁面那槽。
■提供豐富的API,如掃一掃猿诸、支付等微信特有能力饼暑。
■每個頁面有獨立的作用域稳析,并提供模塊化能力。
但同時撵孤,由于框架并非運行在瀏覽器中迈着,所以JavaScript在Web中的一些能力都將無法使用,比如document邪码、window等裕菠,這也給開發(fā)帶來相應的挑戰(zhàn)。
邏輯層的實現(xiàn)就是編寫各個頁面的.js腳本文件闭专。開發(fā)者編寫的所有代碼最終將會打包成一份JavaScript奴潘,并在小程序啟動的時候運行旧烧,直到小程序銷毀。類似ServiceWorker画髓,所以邏輯層也稱為App Service掘剪。
注冊程序~App()方法
在邏輯層,App()方法用來注冊一個小程序奈虾。App()接受一個object參數(shù)夺谁,用于指定小程序的生命周期函數(shù)等。App()方法有且僅有一個肉微,存在于app.js中匾鸥。object參數(shù)說明參見表
參數(shù) | 類型 | 描述 | 觸發(fā)時機 |
---|---|---|---|
onLaunch | Function | 生命周期函數(shù)-監(jiān)聽小程序初始化 | 當小程序初始化完成時,會觸發(fā)onLaunch碉纳,全局只觸發(fā)一次 |
onShow | Function | 生命周期函數(shù)-監(jiān)聽小程序顯示 | 當小程序啟動勿负,或從后臺進入前臺顯示,會觸發(fā)onShow |
onHide | Function | 生命周期函數(shù)-監(jiān)聽小程序隱藏 | 當小程序進入后臺劳曹,會觸發(fā)onHide |
onError | Function | 錯誤監(jiān)聽函數(shù) | 當小程序發(fā)生腳本錯誤奴愉,或者API調用失敗時,會觸發(fā)onError并帶上錯誤信息 |
其它 | Any | 開發(fā)者可以添加任意的函數(shù)或數(shù)據(jù)到Object參數(shù)中铁孵,用this可以訪問 | 锭硼。。蜕劝。 |
前臺账忘、后臺:
- 用戶當前界面運行或操作小程序時為前臺;
- 當用戶點擊左上角關閉熙宇,或者按了設備Home鍵離開微信,小程序并沒有直接銷毀溉浙,而是進入了后臺烫止;
- 當再次進入微信或再次打開小程序,又會從后臺進入前臺戳稽。
- 銷毀:只有當小程序進入后臺一定時間馆蠕,或者系統(tǒng)資源占用過高,才會被真正銷毀惊奇。此時代表小程序的生命周期結束互躬。
周期代碼:
App({
onLaunch: function() { // 啟動時執(zhí)行的初始化工作 },
onShow: function() { // 小程序進入前臺時執(zhí)行的操作 },
onHide: function() { // 小程序進入后臺時執(zhí)行的操作 },
onError: function(msg) { console.log(msg) },
globalData: 'I am global data' })
微信團隊為開發(fā)者提供了全局的getApp()函數(shù),可以用來獲取小程序實例颂郎。
// other.js var appInstance = getApp() console.log(appInstance.globalData) //I am global data
注意
■App()方法須在app.js中注冊吼渡,且不能注冊多個。
■不要在定義App()內的函數(shù)中調用getApp()乓序,使用this就可以拿到App實例寺酪。
■通過getApp()獲取實例之后坎背,不要私自調用生命周期函數(shù)(如onLaunch、onShow寄雀、onHide等)得滤。
注冊頁面~Page()方法
在邏輯層,Page()方法用來注冊一個頁面盒犹。Page()接受一個object參數(shù)懂更,用于指定頁面的初始數(shù)據(jù)、生命周期函數(shù)急膀、事件處理函數(shù)等沮协。Page()方法,每個頁面有且僅有一個脖阵,存在于該頁面的.js文件中皂股。object參數(shù)說明參見表
參數(shù) | 類型 | 描述 |
---|---|---|
data | Object | 頁面的初始數(shù)據(jù) |
onLoad | Function | 生命周期函數(shù)-監(jiān)聽頁面加載 |
onReady | Function | 生命周期函數(shù)-監(jiān)聽頁面初次渲染完成 |
onShow | Function | 生命周期函數(shù)-監(jiān)聽頁面顯示 |
onHide | Function | 生命周期函數(shù)-監(jiān)聽頁面隱藏 |
onUnload | Function | 生命周期函數(shù)-監(jiān)聽頁面卸載 |
onPullDownRefresh | Function | 頁面相關事件處理函數(shù)-監(jiān)聽用戶下拉動作 |
onReachBottom | Function | 頁面上拉觸底事件的處理函數(shù) |
onShareAppMessage | Function | 用戶點擊右上角分享 |
其它 | Any | 開發(fā)者可以添加任意的函數(shù)或數(shù)據(jù)到Object參數(shù)中,用this可以訪問 |
Page()方法示例代碼如下:
// index.js
Page({
data: {
text: "This is page data."
},
onLoad: function(options) { // 頁面加載時的初始化操作
},
onReady: function() { // 頁面初次渲染完成時執(zhí)行的操作
},
onShow: function() { // 頁面顯示時執(zhí)行的操作
},
onHide: function() { // 頁面隱藏時執(zhí)行的操作
},
onUnload: function() { // 頁面卸載/關閉時執(zhí)行的操作
},
onPullDownRefresh: function() { // 用戶在頁面下拉時執(zhí)行的操 作 },
onReachBottom: function() { // 到達頁面底部時執(zhí)行的操作
},
onReachBottom: function() { // 到達頁面底部時執(zhí)行的操作
},
onShareAppMessage: function() { // 用戶分享時返回定制的分享 數(shù)據(jù) },
// 事件處理
viewTap: function() {
this.setData({
text: 'Set some data for updating view.'
})
}
})
同樣命黔,微信團隊為開發(fā)者提供了getCurrentPage()函數(shù)呜呐,用來獲取當前頁面的實例。
注意
不要在App()中進行onLaunch操作的時候調用getCurrentPage()悍募,此時page還沒有生成蘑辑。
1.初始化數(shù)據(jù)
初始化數(shù)據(jù)將作為頁面的第一次渲染。對象data將會以JSON的形式由邏輯層傳至視圖層坠宴,所以其數(shù)據(jù)必須是可以轉成JSON的格式:字符串洋魂、數(shù)字、布爾值喜鼓、對象副砍、數(shù)組。
視圖層可以通過WXML對數(shù)據(jù)進行綁定庄岖。
示例代碼如下:
// wxml
// 渲染page()的數(shù)據(jù)
<view>{{text}}</view>
<view>{{array[0].msg}}</view>
//page.js
//page()中的初始化數(shù)據(jù)data
Page({
data:{
text:'init data',
array:[{msg:'1'},{msg:'2'}]
}
})
2.生命周期函數(shù)使用
onLoad是頁面加載時執(zhí)行的初始化操作:
■一個頁面只會調用一次豁翎。
■參數(shù)可以獲取wx.navigateTo和wx.redirectTo及中的query。
onShow是頁面顯示時執(zhí)行的操作隅忿。每次打開頁面都會調用一次心剥。
onReady是頁面初次渲染完成時執(zhí)行的操作:
■一個頁面只會調用一次,代表頁面已經準備妥當背桐,可以和視圖層進行交互优烧。
■對頁面的設置(如wx.setNavigationBarTitle)請在onReady之后設置。
onHide是頁面隱藏時執(zhí)行的操作链峭。當navigateTo或底部進行tab切換時調用畦娄。
onUnload是頁面卸載時執(zhí)行的操作。當進行redirectTo或navigateBack操作的時候調用。
3.頁面相關事件處理函數(shù)
onPullDownRefresh是下拉刷新時執(zhí)行的操作纷责,例如:
■監(jiān)聽用戶下拉刷新事件捍掺。
■需要在頁面.json文件的window配置項中開啟enablePullDownRefresh。
■當處理完數(shù)據(jù)刷新后再膳,wx.stopPullDownRefresh可以停止當前頁面的下拉刷新挺勿。onShareAppMessage是用戶分享時返回定制的分享內容:
■只有定義了此事件處理函數(shù),右上角菜單才會顯示“分享”按鈕喂柒。
■用戶點擊分享按鈕的時候會調用不瓶。
■此事件需要return一個Object,用于自定義分享內容灾杰。
onShareAppMessage自定義分享字段如下:
字段 | 說明 | 默認值 |
---|---|---|
title | 分享標題 | 當前小程序名稱 |
path | 分享路徑 | 當前頁面path,必須以/開頭的完整路徑 |
onShareAppMessage示例代碼如下:
Page({
onShareAppMessage: function () {
return {
title: ’自定義分享標題’,
path: '/page/user? id=123'
}
}
})
4.事件處理函數(shù)
除了初始化數(shù)據(jù)和生命周期函數(shù)蚊丐,Page()方法中還可以定義一些特殊的函數(shù):事件處理函數(shù)。我們可在視圖層通過對組件加入事件綁定艳吠,當滿足觸發(fā)事件時麦备,就會執(zhí)行Page()中定義的事件處理函數(shù)。
示例代碼如下:
// // 綁定tap事件到view組件上昭娩,處理事件的函數(shù)名為viewTap click me // page.js Page({ // 定義一個viewTap事件處理函數(shù) viewTap: function() { console.log('view tap') } })
5.頁面數(shù)據(jù)設置及展現(xiàn)
在Page()中凛篙,我們要使用setData函數(shù)來將數(shù)據(jù)從邏輯層發(fā)送到視圖層,同時改變對應的this.data的值栏渺。
注意
■this是包含它的函數(shù)作為方法被調用時所屬的對象呛梆,在小程序中一般指調用頁面。
■直接修改this.data無效磕诊,無法改變頁面的狀態(tài)填物,還會造成數(shù)據(jù)不一致。
■單次設置的數(shù)據(jù)不能超過1024KB霎终,請盡量避免一次設置過多的數(shù)據(jù)滞磺。
setData()函數(shù)的參數(shù)接受一個對象。以“key, value”的形式表示將this.data中的key對應的值改變成value莱褒。其中key可以非常靈活雁刷,包括以數(shù)據(jù)路徑的形式給出,如array[2].message, a.b.c.d保礼,并且無須在this.data中預先定義。
示例代碼如下:
// wxml
<view>{{text}}</view>
<button bindtap="changeText">Change normal data</button>
<view>{{array[0].text}}</view>
<button bindtap="changeItemInArray">Change Array data</button>
<view>{{objc.text}}<view>
<button bindtap="changeItemInObject">Change Object data</button>
<view>{{newField.text}}</view>
<button bindtap="addNewField">Add new data</button>
// index.js Page({ data: { text: 'init data', array: [{text: 'init data'}], object: { text: 'init data' } }, changeText: function() { //這樣設置this.data.text = 'changed data’是不行的责语,會出錯 this.setData({ text: 'changed data' }) }, changeItemInArray: function() { // 可以這樣使用setData以修改動態(tài)的數(shù)據(jù)路徑 this.setData({ 'array[0].text':'changed data' }) }, changeItemInObject: function(){ this.setData({ 'object.text': 'changed data' }); }, addNewField: function() { this.setData({ 'newField.text': 'new data' }) } })
6.頁面棧及其實例獲取
框架以棧的形式維護了當前的所有頁面炮障。當發(fā)生路由切換的時候,頁面棧的表現(xiàn)如下:
路由方式 | 頁面棧表現(xiàn) |
---|---|
初始化 | 新頁面入棧 |
打開新頁面 | 新頁面入棧 |
頁面重定向 | 當前頁面出棧坤候,新頁面入棧 |
頁面返回 | 頁面不斷出棧胁赢,直到目標返回頁,新頁面入棧 |
Tab切換 | 當前頁面出棧白筹,新頁面入棧 |
getCurrentPages()函數(shù)用于獲取當前頁面棧的實例智末,以數(shù)組形式按棧的順序給出谅摄,第一個元素為首頁,最后一個元素為當前頁面系馆。
注意
不要嘗試修改頁面棧送漠,會導致路由以及頁面狀態(tài)錯誤。
7.理解頁面的生命周期
Page與實例的生命周期:
從圖中可以看到由蘑,左邊是視圖層(.wxml與.wxss文件)闽寡,右邊是邏輯層(.js文件)。頁面初始化后尼酿,在整個生命周期中持續(xù)進行相應的業(yè)務數(shù)據(jù)準備爷狈、數(shù)據(jù)展現(xiàn)及響應事件處理、數(shù)據(jù)保存等裳擎,直到頁面卸載涎永。
8.頁面的路由
在小程序中,所有頁面的路由全部由框架進行管理鹿响,對于路由的觸發(fā)方式以及頁面生命周期函數(shù)參見表
路由方式 | 觸發(fā)時機 | 路由后頁面 | 路由前頁面 |
---|---|---|---|
初始化 | 小程序打開的第一個頁面 | onLoad羡微、onShow | ... |
打開新頁面 | 調用API wx.navigateTo或使用組件<navigator open-type="navigator"> | onLoad、onShow | onHide |
頁面重定向 | 調用API wx.redirectTo或使用組件<navigator open-type="redirect"/> | onLoad抢野、onShow | onUnload |
頁面返回 | 調用API wx.navigateBack或者用戶按左上角返回按鈕 | onShow | onUnload |
Tab切換 | 調用API wx.switchTab或者使用組件<navigator open-type="switchTab"/>或多個Tab模式下用戶切換Tab | 第一次打開onLoad\onShow\否則onShow | onHide |
模塊及調用
1.文件作用域
在頁面的JavaScript(.js)腳本文件中聲明的變量和函數(shù)只在該文件中有效拷淘;不同的文件中可以聲明相同名字的變量和函數(shù),不會互相影響指孤。
通過全局函數(shù)getApp()可以獲取全局的應用實例启涯,如果需要全局的數(shù)據(jù)可以在App()中設置,例如:
// app.js App({ globalData: 1 }) // a.js
// 變量localValue只在a.js文件中有效
var localValue = 'a'
// 獲取App實例
var app = getApp()
// 獲取全局數(shù)據(jù)值并修改
app.globalData++ // b.js
// 可以在b.js文件中重新定義變量localValue恃轩,這并不會影響a.js文件中的localValue
var localValue = 'b'
// 若a.js在b.js運行结洼,那么這里的globalData就應是2
console.log(getApp().globalData)
2.模塊化
我們可以將一些公共的代碼抽離成為一個單獨的js腳本文件,作為一個模塊叉跛。
注意
模塊只有通過module.exports才能對外暴露接口以供其他.js文件引入使用松忍。
示例代碼如下:
//common.js
function sayHello(name){
console.log('Hello'+name+'!')
}
module.exports = {
sayHello:sayHello
}
在需要使用這些模塊的.js文件中,使用require(path)將公共代碼引入筷厘。
示例代碼如下:
//call.js
var common = require('common.js')
Page({
helloMINA:function(){
common.sayHello('MINA')
}
})
微信原生API
微信原生的API共有八大類:網絡API鸣峭、媒體API、文件API酥艳、數(shù)據(jù)緩存API摊溶、位置API、設備API充石、界面API以及微信開放接口莫换。
在使用這些微信原生API之前,我們先看看注意事項:
■wx.on開頭的API是監(jiān)聽某個事件發(fā)生的API接口,接受一個回調(CALLBACK)函數(shù)作為參數(shù)拉岁。當該事件觸發(fā)時坷剧,會調用該回調函數(shù)。
■如未特殊約定喊暖,其他API接口都接受一個OBJECT作為參數(shù)惫企。
■object中可以指定success、fail哄啄、complete來接收接口調用結果(見下表)
參數(shù)名 | 類型 | 必填 | 說明 |
---|---|---|---|
Success | Function | 否 | 接口調用成功的回調函數(shù) |
Fail | Function | 否 | 接口調用失敗的回調函數(shù) |
Complete | Function | 否 | 接口調用結束的回調函數(shù)(調用成功雅任、失敗都會執(zhí)行) |
微信原生API列表名稱及主要用途:
網絡API:
名稱 | 主要用途 |
---|---|
wx.request | 發(fā)起網絡請求 |
wx.uploadFile | 上傳文件 |
wx.downloadFile | 下載文件 |
wx.connectSocket | 創(chuàng)建WebSocket連接 |
wx.onSocketOpen | 監(jiān)聽WebSocket打開 |
wx.onSocketError | 監(jiān)聽WebSocket錯誤 |
wx.sendSocketMessage | 發(fā)送WebSocket消息 |
wx.onSocketMessage | 接收WebSocket消息 |
wx.closeSocket | 關閉WebSocket連接 |
wx.onSocketClose | 監(jiān)聽WebSocket關閉 |
媒體API:
名稱 | 主要用途 |
---|---|
wx.chooseImage | 從相冊選擇圖片或拍照 |
wx.previewImage | 預覽圖片 |
wx.getImageInfo | 獲取圖片信息 |
wx.startRecord、wx.StopRecord | 開始錄音咨跌、結束錄音 |
wx.playVoice沪么、wx.pauseVoice、wx.stopVoice | 播放語音锌半、暫停播放語音禽车、結束播放語音 |
wx.createAudioContext | 創(chuàng)建并返回audio的上下文對象 |
wx.getBackgroundAudioPlayState | 獲取音樂播放狀態(tài) |
wx.playBackgroundAudio | 播放音樂 |
wx.pauseBackgroundAudio | 暫停播放音樂 |
wx.seekBackgroundAudio | 控制音樂播放進度 |
wx.stopBackgroundAudio | 停止播放音樂 |
wx.onBackgroundAudioPlay | 監(jiān)聽音樂開始播放 |
wx.onBackgroundAudioPause | 監(jiān)聽音樂暫停 |
wx.onBackgroundAudioStop | 監(jiān)聽音樂結束 |
wx.chooseVideo | 從相冊選擇視頻或者拍攝 |
wx.createVideoContext | 創(chuàng)建并video的上下文對象 |
文件API:
名稱 | 主要用途 |
---|---|
wx.saveFile | 保存文件 |
wx.getSavedFileList | 獲取本地已保存的文件列表 |
wx.getSavedFileInfo | 獲取本地文件的文件信息 |
wx.removeSavedFile | 刪除本地儲存的文件 |
wx.openDocument | 新開頁面打開文檔,支持格式doc刊殉、xls殉摔、ppt、doc记焊、xlsx逸月、pptx |
數(shù)據(jù)緩存API:
名稱 | 主要用途 |
---|---|
wx.getStorge(wx.getStorgeSync) | 異步獲取本地數(shù)據(jù)緩存(同步) |
wx.setStorge(wx.setStorgeSync) | 異步設置本地數(shù)據(jù)緩存(同步) |
wx.removeStorge(wx.removeStorgeSync) | 異步移除本地指定key(同步) |
wx.clearStorge(wx.clearStorgeSync) | 異步清理本地數(shù)據(jù)緩存(同步) |
位置API:
名稱 | 主要用途 |
---|---|
wx.getLocation | 獲取當前位置 |
wx.chooseLocation | 打開內置地圖選擇位置 |
wx.openLocation | 打開內置地圖 |
wx.createMapContext | 創(chuàng)建map的上下文對象 |
設備信息API:
名稱 | 主要用途 |
---|---|
wx.getNetworkType | 獲取網絡類型 |
wx.getSystemInfo(wx.getSystemInfoSync) | 獲取系統(tǒng)信息(同步) |
wx.onAccelerometerChange | 監(jiān)聽重力感應數(shù)據(jù) |
wx.onCompassChange | 監(jiān)聽羅盤數(shù)據(jù) |
wx.makePhoneCall | 調起撥打電話 |
wx.scanCode | 調起客戶端掃碼界面 |
界面API:
名稱 | 主要用途 |
---|---|
wx.showToast、wx.hideToast | 顯示消息提示框遍膜、隱藏消息提示框 |
wx.showModal | 顯示狀態(tài)彈框 |
wx.showActionSheet | 顯示操作菜單 |
wx.setNavigationBarTitle | 設置當前頁面標題 |
wx.showNavigationBarLoading | 顯示導航條加載動畫 |
wx.hideNavigationBarLoading | 隱藏導航條加載動畫 |
wx.navigationTo碗硬、wx.mavigationBack | 新窗口打開頁面、返回頁面 |
wx.redirectTo | 原窗口打開頁面 |
wx.switchTab | 跳轉到Tab頁面 |
wx.createAnimation | 動畫 |
wx.creatCanvasContext | 創(chuàng)建canvas繪圖上下文 |
wx.createContext | 創(chuàng)建繪圖上下文 |
wx.drawCanvas | 繪圖 |
wx.canvasToTempFilePath | 保護畫布內容 |
wx.hideKeyboard | 隱藏鍵盤 |
Page.onPullDownRefresh | 監(jiān)聽頁面用戶下拉刷新 |
wx.stopPullDownRefresh | 停止下拉刷新動畫 |
開放API:
名稱 | 主要用途 |
---|---|
wx.login | 登陸 |
wx.getUserInfo | 獲取用戶信息 |
wx.requestPayment | 發(fā)起微信支付 |