1. 程式人生 > >微信小程式開發《6 .框架之邏輯層》

微信小程式開發《6 .框架之邏輯層》

場景值

基礎庫 1.1.0 開始支援,低版本需做相容處理

當前支援的場景值有:

場景值ID說明
1001發現欄小程式主入口
1005頂部搜尋框的搜尋結果頁
1006發現欄小程式主入口搜尋框的搜尋結果頁
1007單人聊天會話中的小程式訊息卡片
1008群聊會話中的小程式訊息卡片
1011掃描二維碼
1012長按圖片識別二維碼
1013手機相簿選取二維碼
1014小程式模版訊息
1017前往體驗版的入口頁
1019微信錢包
1020公眾號 profile 頁相關小程式列表
1022聊天頂部置頂小程式入口
1023安卓系統桌面圖示
1024小程式 profile 頁
1025掃描一維碼
1026附近小程式列表
1027頂部搜尋框搜尋結果頁“使用過的小程式”列表
1028我的卡包
1029卡券詳情頁
1030自動化測試下開啟小程式
1031長按圖片識別一維碼
1032手機相簿選取一維碼
1034微信支付完成頁
1035公眾號自定義選單
1036App 分享訊息卡片
1037小程式開啟小程式
1038從另一個小程式返回
1039搖電視
1042新增好友搜尋框的搜尋結果頁
1043公眾號模板訊息
1044帶 shareTicket 的小程式訊息卡片
1047掃描小程式碼
1048長按圖片識別小程式碼
1049手機相簿選取小程式碼
1052卡券的適用門店列表
1053搜一搜的結果頁
1054頂部搜尋框小程式快捷入口
1056音樂播放器選單
1057錢包中的銀行卡詳情頁
1058公眾號文章
1059體驗版小程式繫結邀請頁
1064微信連Wi-Fi狀態列
1067公眾號文章廣告
1068附近小程式列表廣告
1071錢包中的銀行卡列表頁
1072二維碼收款頁面
1073客服訊息列表下發的小程式訊息卡片
1074公眾號會話下發的小程式訊息卡片
1078連Wi-Fi成功頁
1089微信聊天主介面下拉
1090長按小程式右上角選單喚出最近使用歷史
1092城市服務入口

可以在 App 的 onlaunch 和 onshow 中獲取上述場景值,部分場景值下還可以獲取來源應用、公眾號或小程式的appId。詳見

Tip: 由於Android系統限制,目前還無法獲取到按 Home 鍵退出到桌面,然後從桌面再次進小程式的場景值,對於這種情況,會保留上一次的場景值。

註冊頁面Page

Page() 函式用來註冊一個頁面。接受一個 object 引數,其指定頁面的初始資料、生命週期函式、事件處理函式等。

object 引數說明:

屬性型別描述
dataObject頁面的初始資料
onLoadFunction生命週期函式--監聽頁面載入
onReadyFunction生命週期函式--監聽頁面初次渲染完成
onShowFunction生命週期函式--監聽頁面顯示
onHideFunction生命週期函式--監聽頁面隱藏
onUnloadFunction生命週期函式--監聽頁面解除安裝
onPullDownRefreshFunction頁面相關事件處理函式--監聽使用者下拉動作
onReachBottomFunction頁面上拉觸底事件的處理函式
onShareAppMessage         Function使用者點選右上角轉發
onPageScrollFunction頁面滾動觸發事件的處理函式
onTabItemTapFunction當前是 tab 頁時,點選 tab 時觸發
其他Any開發者可以新增任意的函式或資料到 object 引數中,在頁面的函式中用 this 可以訪問

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
  },
  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'
  }
})

初始化資料

初始化資料將作為頁面的第一次渲染。data 將會以 JSON 的形式由邏輯層傳至渲染層,所以其資料必須是可以轉成 JSON 的格式:字串,數字,布林值,物件,陣列。

渲染層可以通過 WXML 對資料進行繫結。

示例程式碼:

<view>{{text}}</view>
<view>{{array[0].msg}}</view>
Page({
  data: {
    text: 'init data',
    array: [{msg: '1'}, {msg: '2'}]
  }
})

生命週期函式

  • onLoad: 頁面載入

    • 一個頁面只會呼叫一次,可以在 onLoad 中獲取開啟當前頁面所呼叫的 query 引數。
  • onShow: 頁面顯示

    • 每次開啟頁面都會呼叫一次。
  • onReady: 頁面初次渲染完成

    • 一個頁面只會呼叫一次,代表頁面已經準備妥當,可以和檢視層進行互動。
    • 對介面的設定如wx.setNavigationBarTitle請在onReady之後設定。
  • onHide: 頁面隱藏

    • navigateTo或底部tab切換時呼叫。
  • onUnload: 頁面解除安裝

    • redirectTonavigateBack的時候呼叫。

onLoad引數

型別說明
Object其他頁面開啟當前頁面所呼叫的 query 引數

頁面相關事件處理函式

  • onPullDownRefresh: 下拉重新整理

    • 監聽使用者下拉重新整理事件。
    • 需要在app.jsonwindow選項中或頁面配置中開啟enablePullDownRefresh
  • onReachBottom: 上拉觸底

    • 監聽使用者上拉觸底事件。
    • 可以在app.jsonwindow選項中或頁面配置中設定觸發距離onReachBottomDistance
    • 在觸發距離內滑動期間,本事件只會被觸發一次。
  • onPageScroll: 頁面滾動

    • 監聽使用者滑動頁面事件。
    • 引數為 Object,包含以下欄位:
欄位型別說明
scrollTopNumber頁面在垂直方向已滾動的距離(單位px)
  • onShareAppMessage: 使用者轉發
    • 只有定義了此事件處理函式,右上角選單才會顯示“轉發”按鈕
    • 使用者點選轉發按鈕的時候會呼叫
    • 此事件需要 return 一個 Object,用於自定義轉發內容

自定義轉發欄位

欄位說明預設值
title轉發標題當前小程式名稱
path轉發路徑當前頁面 path ,必須是以 / 開頭的完整路徑

示例程式碼

Page({
  onShareAppMessage: function () {
    return {
      title: '自定義轉發標題',
      path: '/page/user?id=123'
    }
  }
})

事件處理函式

除了初始化資料和生命週期函式,Page 中還可以定義一些特殊的函式:事件處理函式。在渲染層可以在元件中加入事件繫結,當達到觸發事件時,就會執行 Page 中定義的事件處理函式。

示例程式碼:

<view bindtap="viewTap"> click me </view>
Page({
  viewTap: function() {
    console.log('view tap')
  }
})

Page.prototype.route

route 欄位可以獲取到當前頁面的路徑。

Page.prototype.setData()

setData 函式用於將資料從邏輯層傳送到檢視層(非同步),同時改變對應的 this.data 的值(同步)。

setData() 引數格式

欄位型別必填描述最低版本
dataObject這次要改變的資料
callbackFunction回撥函式1.5.0

object 以 key,value 的形式表示將 this.data 中的 key 對應的值改變成 value。 callback 是一個回撥函式,在這次setData對介面渲染完畢後呼叫。

其中 key 可以非常靈活,以資料路徑的形式給出,如 array[2].messagea.b.c.d,並且不需要在 this.data 中預先定義。

注意:

  1. 直接修改 this.data 而不呼叫 this.setData 是無法改變頁面的狀態的,還會造成資料不一致
  2. 單次設定的資料不能超過1024kB,請儘量避免一次設定過多的資料
  3. 請不要把 data 中任何一項的 value 設為 undefined ,否則這一項將不被設定並可能遺留一些潛在問題。

示例程式碼:

<!--index.wxml-->
<view>{{text}}</view>
<button bindtap="changeText"> Change normal data </button>
<view>{{num}}</view>
<button bindtap="changeNum"> Change normal num </button>
<view>{{array[0].text}}</view>
<button bindtap="changeItemInArray"> Change Array data </button>
<view>{{object.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',
    num: 0,
    array: [{text: 'init data'}],
    object: {
      text: 'init data'
    }
  },
  changeText: function() {
    // this.data.text = 'changed data'  // bad, it can not work
    this.setData({
      text: 'changed data'
    })
  },
  changeNum: function() {
    this.data.num = 1
    this.setData({
      num: this.data.num
    })
  },
  changeItemInArray: function() {
    // you can use this way to modify a danamic data path
    this.setData({
      'array[0].text':'changed data'
    })
  },
  changeItemInObject: function(){
    this.setData({
      'object.text': 'changed data'
    });
  },
  addNewField: function() {
    this.setData({
      'newField.text': 'new data'
    })
  }
})

生命週期

下圖說明了 Page 例項的生命週期。

頁面路由

頁面棧

框架以棧的形式維護了當前的所有頁面。 當發生路由切換的時候,頁面棧的表現如下:

路由方式頁面棧表現
初始化新頁面入棧
開啟新頁面新頁面入棧
頁面重定向當前頁面出棧,新頁面入棧
頁面返回頁面不斷出棧,直到目標返回頁,新頁面入棧
Tab 切換頁面全部出棧,只留下新的 Tab 頁面
重載入頁面全部出棧,只留下新的頁面

getCurrentPages()

getCurrentPages() 函式用於獲取當前頁面棧的例項,以陣列形式按棧的順序給出,第一個元素為首頁,最後一個元素為當前頁面。

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

路由方式

對於路由的觸發方式以及頁面生命週期函式如下:

Tab 切換對應的生命週期(以 A、B 頁面為 Tabbar 頁面,C 是從 A 頁面開啟的頁面,D 頁面是從 C 頁面開啟的頁面為例):

當前頁面路由後頁面觸發的生命週期(按順序)
AANothing happend
ABA.onHide(), B.onLoad(), B.onShow()
AB(再次開啟)A.onHide(), B.onShow()
CAC.onUnload(), A.onShow()
CBC.onUnload(), B.onLoad(), B.onShow()
DBD.onUnload(), C.onUnload(), B.onLoad(), B.onShow()
D(從轉發進入)AD.onUnload(), A.onLoad(), A.onShow()
D(從轉發進入)BD.onUnload(), B.onLoad(), B.onShow()

Tips:

  • navigateToredirectTo 只能開啟非 tabBar 頁面。
  • switchTab 只能開啟 tabBar 頁面。
  • reLaunch 可以開啟任意頁面。
  • 頁面底部的 tabBar 由頁面決定,即只要是定義為 tabBar 的頁面,底部都有 tabBar。
  • 呼叫頁面路由帶的引數可以在目標頁面的onLoad中獲取。

檔案作用域

在 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++
// b.js
// You can redefine localValue in file b.js, without interference with the localValue in a.js.
var localValue = 'b'
// If a.js it run before b.js, now the globalData shoule be 2.
console.log(getApp().globalData)

模組化

可以將一些公共的程式碼抽離成為一個單獨的 js 檔案,作為一個模組。模組只有通過 module.exports 或者 exports 才能對外暴露介面。

需要注意的是:

  • exports 是 module.exports 的一個引用,因此在模組裡邊隨意更改 exports 的指向會造成未知的錯誤。所以更推薦開發者採用 module.exports 來暴露模組介面,除非你已經清晰知道這兩者的關係。
  • 小程式目前不支援直接引入 node_modules , 開發者需要使用到 node_modules 時候建議拷貝出相關的程式碼到小程式的目錄中。
// common.js
function sayHello(name) {
  console.log(`Hello ${name} !`)
}
function sayGoodbye(name) {
  console.log(`Goodbye ${name} !`)
}

module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye

​在需要使用這些模組的檔案中,使用 require(path) 將公共程式碼引入

var common = require('common.js')
Page({
  helloMINA: function() {
    common.sayHello('MINA')
  },
  goodbyeMINA: function() {
    common.sayGoodbye('MINA')
  }
})

Tips

  1. tip: require 暫時不支援絕對路徑