支付寶小程序框架 頁面·運(yùn)行機(jī)制

2020-09-18 10:18 更新

Page(object: Object)

/pages 目錄的 .js 文件中,定義 Page(),用于注冊(cè)一個(gè)小程序頁面,接受一個(gè) object 作為屬性,用來指定頁面的初始數(shù)據(jù)、生命周期回調(diào)、事件處理等。

以下為一個(gè)基本的頁面代碼:

// pages/index/index.js
Page({
  data: {
    title: "Alipay",
  },
  onLoad(query) {
    // 頁面加載
  },
  onShow() {
    // 頁面顯示
  },
  onReady() {
    // 頁面加載完成
  },
  onHide() {
    // 頁面隱藏
  },
  onUnload() {
    // 頁面被關(guān)閉
  },
  onTitleClick() {
    // 標(biāo)題被點(diǎn)擊
  },
  onPullDownRefresh() {
    // 頁面被下拉
  },
  onReachBottom() {
    // 頁面被拉到底部
  },
  onShareAppMessage() {
   // 返回自定義分享信息
  },
  // 事件處理函數(shù)對(duì)象
  events: {
    onBack() {
      console.log('onBack');
    },
  },
  // 自定義事件處理函數(shù)
  viewTap() {
    this.setData({
      text: 'Set data for update.',
    });
  },
  // 自定義事件處理函數(shù)
  go() {
    // 帶參數(shù)的跳轉(zhuǎn),從 page/ui/index 的 onLoad 函數(shù)的 query 中讀取 type
    my.navigateTo({url:'/page/ui/index?type=mini'});
  },
  // 自定義數(shù)據(jù)對(duì)象
  customData: {
    name: 'alipay',
  },
});

頁面生命周期

下圖說明了頁面 Page 對(duì)象的生命周期。

小程序主要靠視圖線程(Webview)和應(yīng)用服務(wù)線程(Worker)來控制管理。視圖線程和應(yīng)用服務(wù)線程同時(shí)運(yùn)行。

  • 應(yīng)用服務(wù)線程啟動(dòng)后運(yùn)行 app.onLauch 和 app.onShow 以完成 App 創(chuàng)建,再運(yùn)行 page.onLoad 和 page.onShow 以完成 Page 創(chuàng)建,此時(shí)等待視圖線程初始化完成通知。
  • 視圖線程初始化完成通知應(yīng)用服務(wù)線程,應(yīng)用服務(wù)線程將初始化數(shù)據(jù)發(fā)送給視圖線程進(jìn)行渲染,此時(shí)視圖線程完成第一次數(shù)據(jù)渲染。
  • 第一次渲染完成后視圖線程進(jìn)入就緒狀態(tài)并通知應(yīng)用服務(wù)線程,應(yīng)用服務(wù)線程調(diào)用 page.onReady 函數(shù)并進(jìn)入活動(dòng)狀態(tài)。
  • 應(yīng)用線程進(jìn)入活動(dòng)狀態(tài)后每次數(shù)據(jù)修改將會(huì)通知視圖線程進(jìn)行渲染。當(dāng)切換頁面進(jìn)入后臺(tái),應(yīng)用線程調(diào)用page.onHide 函數(shù)后,進(jìn)入存活狀態(tài);頁面返回到前臺(tái)將調(diào)用 page.onShow 函數(shù),進(jìn)入活動(dòng)狀態(tài);當(dāng)調(diào)用返回或重定向頁面后將調(diào)用 page.onUnload 函數(shù),進(jìn)行頁面銷毀。

page lifecycle

object 屬性說明

屬性 類型 描述 最低版本
data Object | Function 初始數(shù)據(jù)或返回初始化數(shù)據(jù)的函數(shù)。 -
events Object 事件處理函數(shù)對(duì)象 1.13.7
onLoad Function(query: Object) 頁面加載時(shí)觸發(fā) -
onShow Function 頁面顯示時(shí)觸發(fā) -
onReady Function 頁面初次渲染完成時(shí)觸發(fā) -
onHide Function 頁面隱藏時(shí)觸發(fā) -
onUnload Function 頁面卸載時(shí)觸發(fā) -
onShareAppMessage Function(options: Object) 點(diǎn)擊右上角分享時(shí)觸發(fā) -
onTitleClick Function 點(diǎn)擊標(biāo)題觸發(fā) -
onOptionMenuClick Function 點(diǎn)擊導(dǎo)航欄額外圖標(biāo)觸發(fā),設(shè)置額外圖標(biāo) 1.3.0
onPopMenuClick Function 點(diǎn)擊右上角通用菜單中的自定義菜單按鈕觸發(fā) 1.3.0
onPullDownRefresh Function({from: manual code}) 頁面下拉時(shí)觸發(fā) -
onPullIntercept Function 下拉中斷時(shí)觸發(fā) 1.11.0
onTabItemTap Function 點(diǎn)擊tabItem時(shí)觸發(fā) 1.11.0
onPageScroll Function({scrollTop}) 頁面滾動(dòng)時(shí)觸發(fā) -
onReachBottom Function 上拉觸底時(shí)觸發(fā) -
其他 Any 開發(fā)者可以添加任意的函數(shù)或?qū)傩缘?nbsp;object 中,在頁面的函數(shù)中可以用 this 來訪問 -

頁面數(shù)據(jù)對(duì)象 data

通過設(shè)置 data 指定頁面的初始數(shù)據(jù)。當(dāng) data 為對(duì)象時(shí),被所有頁面共享。 即:當(dāng)該頁面回退后再次進(jìn)入該頁面時(shí),會(huì)顯示上次頁面的數(shù)據(jù),而非初始數(shù)據(jù)。這種情況,可以通過設(shè)置 data 為不可變數(shù)據(jù)或者變更 data 為頁面獨(dú)有數(shù)據(jù)兩種方式來解決。

設(shè)置為不可變數(shù)據(jù)

Page({
 data: { arr:[] },
 doIt() {
   this.setData({arr: [...this.data.arr, 1]});
 },
});

設(shè)置頁面獨(dú)有數(shù)據(jù)(不推薦修改數(shù)據(jù))

Page({
 data() { return { arr:[] }; },
 doIt() {
   this.setData({arr: [1, 2, 3]});
 },
});

注意:不要直接修改 this.data,無法改變頁面的狀態(tài),還會(huì)造成數(shù)據(jù)不一致。

比如:

Page({
 data: { arr:[] },
 doIt() {
   this.data.arr.push(1); // 不要這么寫!
   this.setData({arr: this.data.arr});
 }
});

生命周期函數(shù)

onLoad(query: Object)

頁面初始化時(shí)觸發(fā)。一個(gè)頁面只會(huì)調(diào)用一次。 query 為 my.navigateTomy.redirectTo 中傳遞的 query 對(duì)象。 query 內(nèi)容格式為:“參數(shù)名=參數(shù)值&參數(shù)名=參數(shù)值…”。

屬性 類型 描述
query Object 打開當(dāng)前頁面路徑中的參數(shù)

onShow()

頁面顯示/切入前臺(tái)時(shí)觸發(fā)。

onReady()

頁面初次渲染完成時(shí)觸發(fā)。 一個(gè)頁面只會(huì)調(diào)用一次,代表頁面已經(jīng)準(zhǔn)備妥當(dāng),可以和視圖層進(jìn)行交互。 對(duì)界面的設(shè)置,如 my.setNavigationBar 請(qǐng)?jiān)?onReady 之后設(shè)置。

onHide()

頁面隱藏/切入后臺(tái)時(shí)觸發(fā)。 如 my.navigateTo 到其他頁面或底部 tab 切換等。

onUnload()

頁面卸載時(shí)觸發(fā)。 如 my.redirectTomy.navigateBack 到其他頁面等。

頁面事件處理函數(shù)

onShareAppMessage(options: Object)

在 Page 中定義 onShareAppMessage 函數(shù),設(shè)置該頁面的分享信息。

  • 每個(gè) Page 頁面的右上角菜單中默認(rèn)有 分享 按鈕;onShareAppMessage 函數(shù)只自定義分享的內(nèi)容,不影響分享功能。
  • 用戶點(diǎn)擊分享按鈕的時(shí)候會(huì)調(diào)用。
  • 此事件需要返回一個(gè)對(duì)象(Object)類型,用于自定義分享內(nèi)容。
  • 分享圖片中的二維碼的有效期為 60 天,若需要長(zhǎng)期有效的二維碼,請(qǐng)到 開發(fā)者后臺(tái) > 碼管理 中生成。
  • 小程序在 1.1.0+ 版本中開始支持 open-type 為 share 的按鈕觸發(fā)分享。

效果實(shí)例

自定義分享.gif

image

示例代碼

// API-DEMO page/API/share/share.json 
 {
 "defaultTitle" : "onShareAppMessage" 
 }
 <view class = "page" > 
 <view class = "page-description" > 點(diǎn)擊右上角開始自定義分享 </view>
 </view>
// API-DEMO page/API/share/share.js 
 Page ({
  onShareAppMessage () {
  return {
    title : '分享 View 組件' ,
    desc : 'View 組件很通用' ,
    path : 'page/component/view/view' ,
        };
      },
 });

按鈕觸發(fā)分享方式參考代碼:

<view>
 <button type="primary" open-type="share" a:if="{{canIUseShareButton}}">推薦給朋友</button>
</view>
Page({ 
  data: { canIUseShareButton: true }, 
  setShareButtonSwitch () { this.setData({ canIUseShareButton: my.canIUse('button.open-type.share') }) },
 onLoad() { this.setShareButtonSwitch(); } ,

 
 onShareAppMessage() { 
   return {
      title: '小程序示例',
      desc: '小程序官方示例Demo,展示已支持的接口能力及組件。', 
      path: 'page/component/component-pages/view/view?param=123'
       }
       }
 });

入?yún)⑹?Object 類型,屬性如下:

屬性 類型 說明 最低版本
from String 觸發(fā)來源: button:頁面分享按鈕觸發(fā) menu:右上角分享按鈕觸發(fā) code:執(zhí)行 my.showSharePanel 觸發(fā) 1.10.0
target Object 如果 from 值為 button,則 target 為觸發(fā)這次分享的 button,否則為 undefined。 1.10.0
webViewUrl String 頁面中包含 web-view 組件時(shí),返回當(dāng)前 web-view 的URL。 1.6.0

onShareAppMessage 執(zhí)行后必須返回一個(gè)分享對(duì)象,用于自定義分享內(nèi)容。

返回值

屬性 類型 必填 描述 最低版本
title String 自定義分享標(biāo)題。 -
desc String 自定義分享描述:由于分享到微博只支持最大長(zhǎng)度 140 個(gè)字,因此建議長(zhǎng)度不要超過該限制。 -
path String 自定義分享頁面的路徑,path中的自定義參數(shù)可在小程序生命周期的 onLoad方法中獲?。▍?shù)傳遞遵循 http get 的傳參規(guī)則)。path 路徑里不能帶根目錄 / 。 -
content String 自定義吱口令文案,最多 28 個(gè)字符。 1.7.0
imageUrl String 自定義分享小圖 icon 元素,支持:網(wǎng)絡(luò)圖片路徑;apFilePath 路徑;相對(duì)路徑。使用場(chǎng)景詳見下方說明。 1.4.0
bgImgUrl String 自定義分享預(yù)覽大圖,建議尺寸750x825,支持:網(wǎng)絡(luò)圖片路徑;apFilePath路徑(客戶端10.1.58版本開始支持);相對(duì)路徑(客戶端 10.1.58 版本開始支持)。使用場(chǎng)景詳見下方說明。 1.9.0
searchTip String 生成分享截圖的搜索引導(dǎo),設(shè)置該參數(shù)后,會(huì)在分享圖片中增加上支付寶搜“設(shè)置關(guān)鍵字”的內(nèi)容,設(shè)置關(guān)鍵字不能超過5個(gè)字。 -
success Function 分享成功后回調(diào)。 1.4.0
fail Function 分享失敗后回調(diào)。 1.4.0

success 回調(diào)函數(shù)

屬性 類型 描述
channelName String 分享所選擇的渠道
shareResult Boolean 分享是否成功

onTitleClick()

點(diǎn)擊標(biāo)題時(shí)觸發(fā)。

onOptionMenuClick()

點(diǎn)擊導(dǎo)航欄額外圖標(biāo)觸發(fā),設(shè)置額外圖標(biāo)

onPopMenuClick()

點(diǎn)擊右上角通用菜單中的自定義菜單按鈕觸發(fā)。

onPullDownRefresh({from: manual|code})

下拉刷新時(shí)觸發(fā)。 需要先在 app.jsonwindow 選項(xiàng)中開啟 pullRefresh 。當(dāng)處理完數(shù)據(jù)刷新后,my.stopPullDownRefresh 可以停止當(dāng)前頁面的下拉刷新。

onPullIntercept()

下拉中斷時(shí)觸發(fā)。

onTabItemTap(object: Object)

點(diǎn)擊 tabItem 時(shí)觸發(fā)。

屬性 類型 描述
from String 點(diǎn)擊來源
pagePath String 被點(diǎn)擊 tabItem 的頁面路徑
text String 被點(diǎn)擊 tabItem 的按鈕文字
index Number 被點(diǎn)擊 tabItem 的序號(hào),從0開始

onPageScroll({scrollTop})

頁面滾動(dòng)時(shí)觸發(fā),scrollTop 為頁面滾動(dòng)距離。

onReachBottom()

上拉觸底時(shí)觸發(fā)。

onReachBottom()是在上拉觸底時(shí)才會(huì)觸發(fā),如果頁面已經(jīng)在頁面底部繼續(xù)上拉是不會(huì)再次觸發(fā)。

可以配合 my.pageScrollTo 向上滾動(dòng)一點(diǎn)位置或者在底部增加數(shù)據(jù)等方式讓頁面不是處在底部位置達(dá)到可以連續(xù)上拉觸發(fā)onReachBottom()的效果。

events

為了使代碼更加簡(jiǎn)潔,提供了新的事件處理對(duì)象 events。 已有的頁面處理事件函數(shù)跟直接在 page 實(shí)例上暴露的事件函數(shù)等價(jià)。

注意:

  • events 從基礎(chǔ)庫 1.13.7 版本 開始支持。
  • 請(qǐng)正確區(qū)分頁面事件函數(shù)與 events 內(nèi)同名事件函數(shù)的基礎(chǔ)庫版本要求。

以下是 events 支持的事件函數(shù)列表:

事件 類型 描述 最低版本
onBack Function 頁面返回時(shí)觸發(fā) 1.13.7
onKeyboardHeight Function 鍵盤高度變化時(shí)觸發(fā) 1.13.7
onOptionMenuClick Function 點(diǎn)擊導(dǎo)航欄額外圖標(biāo)觸發(fā),設(shè)置額外圖標(biāo) 1.13.7
onPopMenuClick Function 點(diǎn)擊右上角通用菜單中的自定義菜單按鈕觸發(fā) 1.13.7
onPullIntercept Function 下拉截?cái)鄷r(shí)觸發(fā) 1.13.7
onPullDownRefresh Function({from: manual/code}) 頁面下拉時(shí)觸發(fā) 1.13.7
onTitleClick Function 點(diǎn)擊標(biāo)題觸發(fā) 1.13.7
onTabItemTap Function 點(diǎn)擊非當(dāng)前 tabItem 后觸發(fā) 1.13.7
beforeTabItemTap Function 點(diǎn)擊非當(dāng)前 tabItem 前觸發(fā) 1.13.7
onResize Function({size: {windowWidth: number, windowHeight: number}}) window尺寸改變時(shí)觸發(fā) 1.16.0

示例代碼:

// 特征檢測(cè)
my.canIUse('page.events.onBack');


Page({
  data: {
    text: 'This is page data.'
  },
  onLoad(){
    // 頁面加載時(shí)觸發(fā)
  },
  events:{
    onBack(){
      // 頁面返回時(shí)觸發(fā)
    },
    onKeyboardHeight(e){
      // 鍵盤高度變化時(shí)觸發(fā)
      console.log('鍵盤高度:', e.height)
    },
    onOptionMenuClick(){
      // 點(diǎn)擊右上角菜單按鈕觸發(fā)
    },
    onPopMenuClick(e){
      // 點(diǎn)擊右上角通用菜單中的自定義菜單按鈕觸發(fā)
      console.log('用戶點(diǎn)擊自定義菜單的索引', e.index)
      console.log('用戶點(diǎn)擊自定義菜單的name', e.name)
      console.log('用戶點(diǎn)擊自定義菜單的menuIconUrl', e.menuIconUrl)
    },
    onPullIntercept(){
      // 下拉截?cái)鄷r(shí)觸發(fā)
    },
    onPullDownRefresh(e){
      // 頁面下拉時(shí)觸發(fā)。e.from的值是“code”表示startPullDownRefresh觸發(fā)的事件;值是“manual”表示用戶下拉觸發(fā)的下拉事件
      console.log('觸發(fā)下拉刷新的類型', e.from)
      my.stopPullDownRefresh()
    },
    onTitleClick(){
      // 點(diǎn)擊標(biāo)題觸發(fā)
    },
    onTabItemTap(e){
      // e.from是點(diǎn)擊且切換tabItem后觸發(fā),值是“user”表示用戶點(diǎn)擊觸發(fā)的事件;值是“api”表示switchTab觸發(fā)的事件
      console.log('觸發(fā)tab變化的類型', e.from)
      console.log('點(diǎn)擊的tab對(duì)應(yīng)頁面的路徑', e.pagePath)
      console.log('點(diǎn)擊的tab的文字', e.text)
      console.log('點(diǎn)擊的tab的索引', e.index)
    },
    beforeTabItemTap(){
      // 點(diǎn)擊但切換tabItem前觸發(fā)
    },
    onResize(e){
      // window尺寸改變時(shí)觸發(fā)
      var {windowWidth, windowHeight} = e.size
      console.log('改變后window的寬度', windowWidth)
      console.log('改變后window的高度', windowHeight)
    },
  }
})

Page.prototype.setData(data: Object, callback: Function)

setData 會(huì)將數(shù)據(jù)從邏輯層發(fā)送到視圖層,同時(shí)改變對(duì)應(yīng)的 this.data 的值。

Objectkey: value 的形式表示,將 this.data 中的 key 對(duì)應(yīng)的值改變成 value。其中 key 可以非常靈活,以數(shù)據(jù)路徑的形式給出,如 array[2].messagea.b.c.d,可以不需要在 this.data 中預(yù)先定義。

使用過程中,需要注意以下幾點(diǎn):

  1. 直接修改 this.data 無效,無法改變頁面的狀態(tài),還會(huì)造成數(shù)據(jù)不一致。
  2. 僅支持設(shè)置可 JSON 化的數(shù)據(jù)。
  3. 請(qǐng)盡量避免一次設(shè)置過多的數(shù)據(jù)。
  4. 請(qǐng)不要把 data 中任何一項(xiàng)的 value 設(shè)為 undefined ,否則這一項(xiàng)將不被設(shè)置并可能遺留一些潛在問題。

示例代碼:

<view>{{text}}</view>
<button onTap="changeTitle"> Change normal data </button>
<view>{{array[0].text}}</view>
<button onTap="changeArray"> Change Array data </button>
<view>{{object.text}}</view>
<button onTap="changePlanetColor"> Change Object data </button>
<view>{{newField.text}}</view>
<button onTap="addNewKey"> Add new data </button>
<view>hello: {{name}}</view>
<button onTap="changeName"> Change name </button>
Page({
  data: {
    text: 'test',
    array: [{text: 'a'}],
    object: {
      text: 'blue',
    },
    name: 'taobao',
  },
  changeTitle() {
    // 錯(cuò)誤!不要直接去修改 data 里的數(shù)據(jù)
    // this.data.text = 'changed data'  

    
    // 正確
    this.setData({
      text: 'ha',
    });
  },
  changeArray() {
    // 可以直接使用數(shù)據(jù)路徑來修改數(shù)據(jù)
    this.setData({
      'array[0].text': 'b',
    });
  },
  changePlanetColor(){
    this.setData({
      'object.text': 'red',
    });
  },
  addNewKey() {
    this.setData({
      'newField.text': 'c',
    });
  },
  changeName() {
    this.setData({
      name: 'alipay',
    }, () => { // 接受傳遞回調(diào)函數(shù)
      console.log(this); // this 當(dāng)前頁面實(shí)例
      this.setData({ name: this.data.name + ', ' + 'welcome!'});
    });
  },
});

參數(shù)說明

事件 類型 描述 最低版本
data Object 待改變的數(shù)據(jù) -
callback Function 回調(diào)函數(shù),在頁面渲染更新完成之后執(zhí)行。 使用 my.canIUse('page.setData.callback') 做兼容性處理,詳見 1.7.0。

Page.prototype.$spliceData(data: Object, callback: Function)

說明:$spliceData 自 1.7.2 之后才支持,可以使用 my.canIUse('page.$spliceData') 做兼容性處理,詳見 兼容接口說明。

spliceData 同樣用于將數(shù)據(jù)從邏輯層發(fā)送到視圖層,但是相比于 setData,在處理長(zhǎng)列表的時(shí)候,其具有更高的性能。

Objectkey: value 的形式表示,將 this.data 中的 key 對(duì)應(yīng)的值改變成 value。其中 key 可以非常靈活,以數(shù)據(jù)路徑的形式給出,如 array[2].message、a.b.c.d,可以不需要在 this.data 中預(yù)先定義。value 為一個(gè)數(shù)組(格式:[start, deleteCount, ...items]), 數(shù)組的第一個(gè)元素為操作的起始位置,第二個(gè)元素為刪除的元素的個(gè)數(shù),剩余的元素均為插入的數(shù)據(jù)。對(duì)應(yīng) es5 中數(shù)組的 splice 方法。

示例代碼:

<!-- pages/index/index.axml -->
<view class="spliceData">
  <view a:for="{{a.b}}" key="{{item}}" style="border:1px solid red">
    {{item}}
  </view>
</view>
// pages/index/index.js
Page({
  data: {
    a: {
      b: [1,2,3,4],
    },
  },
  onLoad(){
    this.$spliceData({ 'a.b': [1, 0, 5, 6] });
  },
});

頁面輸出:

1
5
6
2
3
4

參數(shù)說明

事件 類型 描述
data Object 待改變的數(shù)據(jù)
callback Function 回調(diào)函數(shù),在頁面渲染更新完成之后執(zhí)行。

Page.prototype.$batchedUpdates(callback: Function)

批量更新數(shù)據(jù)。

說明$batchedUpdates 自 1.14.0 之后才支持,可以使用 my.canIUse('page.$batchedUpdates') 做兼容性處理,詳見 兼容接口說明。

參數(shù)說明:

事件 類型 描述
callback Function 在此回調(diào)函數(shù)中的數(shù)據(jù)操作會(huì)被批量更新。

下面是示例代碼:

// pages/index/index.js
Page({
  data: {
    counter: 0,
  },
  plus() {
    setTimeout(() => {
      this.$batchedUpdates(() => {
        this.setData({
          counter: this.data.counter + 1,
        });
        this.setData({
          counter: this.data.counter + 1,
        });
      });
    }, 200);
  },
});
<!-- pages/index/index.axml -->
<view>{{counter}}</view>
<button onTap="plus">+2</button>
  • 本示例中每次點(diǎn)擊按鈕,頁面的 counter 會(huì)加 2。
  • setData 放在 this.$batchedUpdates 中,這樣盡管有多次 setData,但是卻只有一次數(shù)據(jù)的傳輸。

Page.route

Page 路徑,對(duì)應(yīng) app.json 中配置的路徑值,類型為 String。這是一個(gè)只讀屬性。

Page({
  onShow() {
    // 對(duì)應(yīng) app.json 中配置的路徑值
    console.log(this.route)
  }
})
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)