小程序:邏輯層

ylbtech-小程序:邏輯層

邏輯層(App Service)

小程序開發框架的邏輯層由 JavaScript 編寫html

邏輯層將數據進行處理後發送給視圖層,同時接受視圖層的事件反饋node

在 JavaScript 的基礎上,咱們作了一些修改,以方便地開發小程序。web

  • 增長 App 和 Page 方法,進行程序和頁面的註冊。
  • 增長 getApp 和 getCurrentPages 方法,分別用來獲取 App 實例和當前頁面棧。
  • 提供豐富的 API,如微信用戶數據,掃一掃,支付等微信特有能力。
  • 每一個頁面有獨立的做用域,並提供模塊化能力。
  • 因爲框架並不是運行在瀏覽器中,因此 JavaScript 在 web 中一些能力都沒法使用,如 documentwindow 等。
  • 開發者寫的全部代碼最終將會打包成一份 JavaScript,並在小程序啓動的時候運行,直到小程序銷燬。相似 ServiceWorker,因此邏輯層也稱之爲 App Service
1. 註冊程序返回頂部

App

App()

App() 函數用來註冊一個小程序。接受一個 object 參數,其指定小程序的生命週期函數等。json

object參數說明:小程序

屬性 類型 描述 觸發時機
onLaunch Function 生命週期函數--監聽小程序初始化 當小程序初始化完成時,會觸發 onLaunch(全局只觸發一次
onShow Function 生命週期函數--監聽小程序顯示 當小程序啓動,或從後臺進入前臺顯示,會觸發 onShow
onHide Function 生命週期函數--監聽小程序隱藏 當小程序從前臺進入後臺,會觸發 onHide
onError Function 錯誤監聽函數 當小程序發生腳本錯誤,或者 api 調用失敗時,會觸發 onError 並帶上錯誤信息
其餘 Any   開發者能夠添加任意的函數或數據到 Object 參數中,用 this 能夠訪問

前臺、後臺定義: 當用戶點擊左上角關閉,或者按了設備 Home 鍵離開微信小程序並無直接銷燬,而是進入了後臺當再次進入微信或再次打開小程序,又會從後臺進入前臺。須要注意的是:只有當小程序進入後臺必定時間,或者系統資源佔用太高,纔會被真正的銷燬api

關閉小程序(基礎庫版本1.1.0開始支持): 當用戶從掃一掃、轉發等入口(場景值爲1007, 1008, 1011, 1025)進入小程序,且沒有置頂小程序的狀況下退出,小程序會被銷燬。數組

小程序運行機制在基礎庫版本 1.4.0 有所改變: 上一條關閉邏輯在新版本已不適用。詳情瀏覽器

示例代碼:微信

App({
  onLaunch: function(options) {
    // Do something initial when launch.
  },
  onShow: function(options) {
      // Do something when show.
  },
  onHide: function() {
      // Do something when hide.
  },
  onError: function(msg) {
    console.log(msg)
  },
  globalData: 'I am global data'
})

onLaunch, onShow 參數

字段 類型 說明
path String 打開小程序的路徑
query Object 打開小程序的query
scene Number 打開小程序的場景值
shareTicket String shareTicket,詳見 獲取更多轉發信息
referrerInfo Object 當場景爲由從另外一個小程序或公衆號或App打開時,返回此字段
referrerInfo.appId String 來源小程序或公衆號或App的 appId,詳見下方說明
referrerInfo.extraData Object 來源小程序傳過來的數據,scene=1037或1038時支持

場景值 詳見app

如下場景支持返回 referrerInfo.appId:

場景值 場景 appId 信息含義
1020 公衆號 profile 頁相關小程序列表 返回來源公衆號 appId
1035 公衆號自定義菜單 返回來源公衆號 appId
1036 App 分享消息卡片 返回來源應用 appId
1037 小程序打開小程序 返回來源小程序 appId
1038 從另外一個小程序返回 返回來源小程序 appId
1043 公衆號模板消息 返回來源公衆號 appId

getApp()

全局的 getApp() 函數能夠用來獲取到小程序實例。

// other.js
var appInstance = getApp()
console.log(appInstance.globalData) // I am global data

 

注意:

  • App() 必須在 app.js 中註冊,且不能註冊多個。
  • 不要在定義於 App() 內的函數中調用 getApp() ,使用 this 就能夠拿到 app 實例。
  • 不要在 onLaunch 的時候調用 getCurrentPages(),此時 page 尚未生成。
  • 經過 getApp() 獲取實例以後,不要私自調用生命週期函數。
2. 場景值返回頂部

場景值

基礎庫 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 公衆號自定義菜單
1036 App 分享消息卡片
1037 小程序打開小程序
1038 從另外一個小程序返回
1039 搖電視
1042 添加好友搜索框的搜索結果頁
1043 公衆號模板消息
1044 帶 shareTicket 的小程序消息卡片(詳情)
1047 掃描小程序碼
1048 長按圖片識別小程序碼
1049 手機相冊選取小程序碼
1052 卡券的適用門店列表
1053 搜一搜的結果頁
1054 頂部搜索框小程序快捷入口
1056 音樂播放器菜單
1058 公衆號文章
1059 體驗版小程序綁定邀請頁
1064 微信連Wifi狀態欄
1067 公衆號文章廣告
1068 附近小程序列表廣告
1072 二維碼收款頁面
1073 客服消息列表下發的小程序消息卡片
1074 公衆號會話下發的小程序消息卡片

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

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

3. 註冊頁面返回頂部

Page

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

object 參數說明:

屬性 類型 描述
data Object 頁面的初始數據
onLoad Function 生命週期函數--監聽頁面加載
onReady Function 生命週期函數--監聽頁面初次渲染完成
onShow Function 生命週期函數--監聽頁面顯示
onHide Function 生命週期函數--監聽頁面隱藏
onUnload Function 生命週期函數--監聽頁面卸載
onPullDownRefresh Function 頁面相關事件處理函數--監聽用戶下拉動做
onReachBottom Function 頁面上拉觸底事件的處理函數
onShareAppMessage Function 用戶點擊右上角轉發
onPageScroll Function 頁面滾動觸發事件的處理函數
其餘 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
  },
  // 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
    • 當處理完數據刷新後,wx.stopPullDownRefresh能夠中止當前頁面的下拉刷新。
  • onReachBottom: 上拉觸底

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

    • 監聽用戶滑動頁面事件。
    • 參數爲 Object,包含如下字段:
字段 類型 說明
scrollTop Number 頁面在垂直方向已滾動的距離(單位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

基礎庫 1.2.0 開始支持,低版本需作兼容處理

route 字段能夠獲取到當前頁面的路徑。

Page.prototype.setData()

setData 函數用於將數據從邏輯層發送到視圖層(異步)同時改變對應的 this.data 的值(同步)

setData() 參數格式

字段 類型 必填 描述 最低版本
data Object 此次要改變的數據  
callback Function 回調函數 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 實例的生命週期。

4. 頁面路由返回頂部

頁面路由

在小程序中全部頁面路由所有由框架進行管理。

頁面棧

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

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

getCurrentPages()

getCurrentPages() 函數用於獲取當前頁面棧的實例,以數組形式按棧的順序給出第一個元素爲首頁最後一個元素爲當前頁面

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

路由方式

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

路由方式 觸發時機 路由前頁面 路由後頁面
初始化 小程序打開的第一個頁面   onLoad, onShow
打開新頁面 調用 API 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"/> 或用戶切換 Tab   各類狀況請參考下表
重啓動 調用 API wx.reLaunch 或使用組件 <navigator open-type="reLaunch"/> onUnload onLoad, onShow

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

當前頁面 路由後頁面 觸發的生命週期(按順序)
A A Nothing happend
A B A.onHide(), B.onLoad(), B.onShow()
A B(再次打開) A.onHide(), B.onShow()
C A C.onUnload(), A.onShow()
C B C.onUnload(), B.onLoad(), B.onShow()
D B D.onUnload(), C.onUnload(), B.onLoad(), B.onShow()
D(從轉發進入) A D.onUnload(), A.onLoad(), A.onShow()
D(從轉發進入) B D.onUnload(), B.onLoad(), B.onShow()

Tips:

  • navigateToredirectTo 只能打開非 tabBar 頁面
  • switchTab 只能打開 tabBar 頁面
  • reLaunch 能夠打開任意頁面
  • 頁面底部的 tabBar 由頁面決定,即只要是定義爲 tabBar 的頁面,底部都有 tabBar。
  • 調用頁面路由帶的參數能夠在目標頁面的onLoad中獲取
5. 模塊化返回頂部

文件做用域

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 暫時不支持絕對路徑

 

6. API返回頂部

小程序開發框架提供豐富的微信原生 API,能夠方便的調起微信提供的能力,如獲取用戶信息,本地存儲,支付功能等。

詳細介紹請參考 API 文檔

7.返回頂部
 
8.返回頂部
 
9.返回頂部
 
10.返回頂部
一、
二、
 
11.返回頂部
 
warn 做者:ylbtech
出處:http://ylbtech.cnblogs.com/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。
相關文章
相關標籤/搜索