邏輯層
1.介紹
小程序開發框架的邏輯層使用JavaScript引擎為小程序提供開發JavaScript代碼的運行環境以及Luffa Cloud小程序的特有功能。
邏輯層將數據進行處理後發送給視圖層,同時接受視圖層的事件迴響。
開發者寫的所有代碼最終將會打包成一份JavaScript文件,並在小程序啟動的時候運行,直到小程序銷毀這一行為類似 SeviceWorker 所以邏輯層也稱之為App Service
在JavaScript的基礎上,我們新增了一些功能,以方便小程序的開發:
- 新增App和Page方法,進行 程序注册 和 頁面注册
- 新增getApp和getCurrentPages方法,分別用來獲取App實例和當前頁面棧。
- 提供豐富的 API,如獲取地理位置,掃一掃等特有能力。
- 提供 模組化 能力,每個頁面有獨立的作用域。
TIP
小程序框架的邏輯層並非運行在瀏覽器中,囙此JavaScript在web中一些能力都無法使用,如window,document等。
2.注册小程序
每個小程序都需要在app.js中調用App(Object)方法注册小程序實例,綁定生命週期回呼函數、錯誤監聽和頁面不存在監聽函數等。
詳細的參數含義和使用請參攷 App
// app.js
App({
onLaunch (options) {
// Do something initial when launch.
},
onShow (options) {
// Do something when show.
},
onHide () {
// Do something when hide.
},
onError (msg) {
console.log(msg)
},
globalData: 'I am global data'
})整個小程序只有一個App實例,是全部頁面共亯的開發者可以通過getApp方法獲取到全域唯一的App實例,獲取App上的數據或調用開發者注册在App上的函數。
// xxx.js
const appInstance = getApp()
console.log(appInstance.globalData) // I am global data3.注册頁面
對於小程序中的每個頁面,都需要在頁面對應的js文件中進行注册,指定頁面的初始數據、生命週期回檔、事件處理函數等。
3.1使用Page構造器注册頁面
簡單的頁面可以使用Page(Object)進行構造。
代碼示例:
// index.js
Page({
data: {
text: "This is page data."
},
onLoad: function(options) {
// Do some initialize when page load.
},
onReady: function() {
// Do something when page ready.
},
onShow: function() {
// Do something when page show.
},
onHide: function() {
// Do something when page hide.
},
onUnload: function() {
// Do something when page close.
},
onPullDownRefresh: function() {
// Do something when pull down.
},
onReachBottom: function() {
// Do something when page reach bottom.
},
onShareAppMessage: function () {
// return custom share data when user share.
},
onPageScroll: function() {
// Do something when page scroll
},
onResize: function() {
// Do something when page resize
},
onTabItemTap(item) {
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
},
// Event handler.
viewTap: function() {
this.setData({
text: 'Set some data for updating view.'
}, function() {
// this is setData callback
})
},
customData: {
hi: 'MINA'
}
})詳細的參數含義和使用請參攷 頁面
3.2使用Component構造器構造頁面
Page構造器適用於簡單的頁面但對於複雜的頁面,Page構造器可能並不好用。
此時,可以使用Component建構器來建構頁面。 Component建構器的主要差異是:方法需要放在methods: { }裡面。
代碼示例:
Component({
data: {
text: "This is page data."
},
methods: {
onLoad: function(options) {
// Executed when the page is created
}, onPullDownRefresh: function() { // Execute on page creation.
onPullDownRefresh: function() {
// onPullDownRefresh: function() { // On page creation }, onPullDownRefresh: function()
}, onPullDownRefresh.
// Event response function
viewTap: function() {
// ...
}
}
})這種創建管道非常類似於 自定義組件,可以像自定義組件一樣使用behaviors等高級特性。
具體細節請閱讀 Component構造器
4.頁面生命週期
下圖說明了頁面Page實例的生命週期:

5.頁面路由
在小程序中所有頁面的路由全部由框架進行管理。
5.1頁面棧
框架以棧的形式維護了當前的所有頁面當發生路由切換的時候,頁面棧的表現如下:
開發者可以使用getCurrentPages()函數獲取當前頁面棧,以數組形式按棧的順序給出,第一個元素為首頁,最後一個元素為當前頁面。
TIP
- 不要嘗試修改頁面棧,會導致路由以及頁面狀態錯誤
- 不要在App.onLaunch的時候調用getCurrentPages(),此時page還沒有生成。
5.2路由管道
對於路由的觸發管道以及頁面生命週期函數如下:
Tab切換對應的生命週期(以A、B頁面為Tabbar頁面,C是從A頁面打開的頁面,D頁面是從C頁面打開的頁面為例):
TIP
- navigateTo,redirectTo只能打開非tabBar頁面。
- switchTab只能打開tabBar頁面。
- reLaunch可以打開任意頁面。
- 頁面底部的tabBar由頁面决定,即只要是定義為tabBar的頁面,底部都有tabBar。
- 調用頁面路由帶的參數可以在目標頁面的onLoad中獲取。
模組化
6.1模組化
可以將一些公共的代碼抽離成為一個單獨的js文件,作為一個模塊模塊只有通過 module.exports 或者exports才能對外暴露接口。
TIP
- exports是module.exports的一個引用,囙此在模塊裡邊隨意更改exports的指向會造成未知的錯誤所以更推薦開發者採用module.exports來暴露模塊接口,除非您已經清晰知道這兩者的關係。
- 小程序現時不支持直接引入node_modules,開發者需要使用到node_modules時候建議拷貝出相關的代碼到小程序的目錄中,或者使用小程序支持的npm功能。
// 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')
}
})6.2文件作用域
在JavaScript文件中聲明的變量和函數只在該文件中有效; 不同的文件中可以聲明相同名字的變量和函數,不會互相影響。
通過全域函數getApp可以獲取全域的應用實例,如果需要全域的數據可以在App()中設定,如:
// app.js
App({
globalData: 1
})// a.js
// The localValue can only be used in file a.js.
var localValue = 'a'
// Get the app instance.
var app = getApp()
// Get the global data and change it.
app.globalData++// a.js
// The localValue can only be used in file a.js.
var localValue = 'a'
// Get the app instance.
var app = getApp()
// Get the global data and change it.
app.globalData++TIP
- 值得注意的是,require引入模塊時,需要使用相對路徑。
7.API
小程序開發框架提供豐富的原生API,可以方便的調起小程序SDK提供的能力,如獲取用戶資訊,本地存儲等詳細介紹請參攷
7.1 事件監聽API
我們約定,以on開頭的API用來監聽某個事件是否觸發,如:wx.onSocketOpen,wx.onCompassChange等。
這類API接受一個回呼函數作為參數,當事件觸發時會調用這個回呼函數,並將相關資料以參數形式傳入。
代碼示例:
wx.onCompassChange(function (res) {
console.log(res.direction)
})7.2 同步API
我們約定,以Sync結尾的API都是同步API,如wx.setStorageSync,wx.getSystemInfoSync等此外,也有一些其他的同步API,如wx.createWorker,wx.getBackgroundAudioManager等,詳情參見API文件中的說明。
同步API的執行結果可以通過函數返回值直接獲取,如果執行出錯會拋出异常。
代碼示例:
try {
wx.setStorageSync('key', 'value')
} catch (e) {
console.error(e)
}7.3 非同步API
大多數API都是非同步API,如wx.request,wx.login等這類API接口通常都接受一個Object類型的參數,這個參數都支持按需指定以下欄位來接收接口調用結果:
Object參數說明
回呼函數的參數
success,fail,complete函數調用時會傳入一個Object類型參數,包含以下欄位:
代碼示例:
wx.login({
success(res) {
console.log(res.code)
}
})