小程序模板網(wǎng)

小程序開發(fā)實用技巧——擴(kuò)展 Page 頁面對象

發(fā)布時間:2018-07-27 12:12 所屬欄目:小程序開發(fā)教程

小程序是通過調(diào)用 Page 函數(shù)來注冊一個頁面的:

//index.js
Page({
  data: {
    text: "This is page data."
  },
  onLoad: function(options) {
    // Do some initialize when page load.
  },
  // Event handler.
  viewTap: function() {
    this.setData({
      text: 'Set some data for updating view.'
    }, function() {
      // this is setData callback
    })
  }
})
復(fù)制代碼

這里 Page 的作用相當(dāng)于構(gòu)造函數(shù), Page 會初始化頁面對象(實例),然后將配置參數(shù)中的屬性 merge 到頁面對象上。

假設(shè)你封裝了個 http 模塊負(fù)責(zé)發(fā)出請求,你想在頁面對象中直接通過 this.http 引用這個模塊,就需要擴(kuò)展頁面對象。要擴(kuò)展一個對象,在 JavaScript 中的常見做法是擴(kuò)展構(gòu)造函數(shù)的 prototype 屬性,這是 Vue 很多插件的實現(xiàn):

import axios from 'axios'
Vue.prototype.axios = axios
// 在 vue 組件中
this.axios.get(api).then(callback)
復(fù)制代碼

很不幸,在小程序中這個辦法無效。 Page 并不是普通的構(gòu)造函數(shù),底層還做了很多其他事情,沒辦法直接通過 Page.prototype 擴(kuò)展頁面對象。

我們可以轉(zhuǎn)變思路,擴(kuò)展傳進(jìn) Page 的配置對象。既然始終要通過調(diào)用 Page 注冊頁面,可以定義一個函數(shù),這個函數(shù)會將收到的配置對象參數(shù)進(jìn)行處理,然后再傳給 Page 。

// wxPage.js
import http from '../utils/http'

const wxPage = function(config) {
  config.http = http
  return Page(config)
}

export default wxPage
復(fù)制代碼

注冊頁面的時候改用這個 wxPage :

import Page from './wxPage'

Page({
  data: {
    text: "This is page data."
  },
  onLoad: function(options) {
    console.log(this.http) // 打印 http 模塊變量
    this.http.get(api).then(callback) // 直接調(diào)用 http 的方法
  },
})
復(fù)制代碼

直接修改 Page 函數(shù)

為了增強頁面對象,每個需要的頁面都得引入 wxPage 是一件不太省心的事;更多時候我們是在維護(hù)一個老項目,需要擴(kuò)展每個原有的頁面對象,這時可以直接修改 Page :

const originalPage = Page //保存原來的Page
Page = function(config) { // 覆蓋Page變量
  config.http = http
  return originalPage(config)
}
復(fù)制代碼

一般來說,修改 Page 的時機(jī)是在 App onLoad 的時候。這樣原有的頁面不用修改,直接就能通過 this.http 拿到 http 。

通過擴(kuò)展 Page 頁面對象實現(xiàn)常見需求

1. 給生命周期方法增加通用邏輯

有時我們希望在頁面注冊的 onLoad 階段執(zhí)行一些通用的邏輯,例如埋點,打 log 等,這時可以改寫配置對象中的 onLoad 方法:

const originalPage = Page
Page = function(config) {
  const { onLoad } = config
  config.onLoad = function(onLoadOptions) {
    // 打 log、埋點……
    console.log('每個頁面都會打出這個log')
    if (typeof onLoad === 'function') {
      onLoad.call(this, onLoadOptions)
    }
  }
  return originalPage(config)
}
復(fù)制代碼

2. 獲取上一頁頁面對象

小程序中的頁面跳轉(zhuǎn)會形成一個頁面棧,棧中存放著每個頁面對象,可以通過getCurrentPages 方法獲得這個頁面棧??梢栽陧撁?nbsp;onLoad 的時候獲取這個頁面棧,然后取出倒數(shù)第二個對象,就是當(dāng)前頁上一頁的頁面對象:

// 接上...
  const { onLoad } = config
  config.onLoad = function(onLoadOptions) {
    const pages = getCurrentPages()
    this.__previousPage = pages[pages.length - 2] // 將上一頁的頁面對象賦為this.__previousPage
    if (typeof onLoad === 'function') {
      onLoad.call(this, onLoadOptions)
    }
  }
  return originalPage(config)
復(fù)制代碼

這樣在頁面對象中可通過引用 this.__previousPage 獲取上一頁頁面對象的data及所有方法,這樣在一些只需要兩個頁面互動的情景下,當(dāng)前頁直接調(diào)用上一個頁面對象的方法(相當(dāng)于回調(diào))后再返回,比通過全局狀態(tài)管理上一頁的數(shù)據(jù)要方便。

3. 跳轉(zhuǎn)頁面并傳遞數(shù)據(jù)到下一頁

這個不多說了,直接看代碼吧:

// 接上
config.navigateTo = function(url, params) { // 實現(xiàn)一個navigateTo方法,參數(shù)包括跳轉(zhuǎn)url和要傳遞的參數(shù)
  this.__params = params
  wx.navigateTo({ url })
}

config.onLoad = function(onLoadOptions) {
  const pages = getCurrentPages()
  this.__previousPage = pages[pages.length - 2] // 將上一頁的頁面對象賦為this.__previousPage
  if (this.__previousPage) {
    onLoadOptions.params = this.__previousPage.__params // 獲取上一頁面的__params賦給onLoad函數(shù)的options
    delete this.__previousPage.__params
  }
  if (typeof onLoad === 'function') {
    onLoad.call(this, onLoadOptions)
  }
}

// A 頁面跳轉(zhuǎn) B 頁面
this.navigateTo('urlToB', { foo: 'bar' })

// B 頁面的 onLoad
Page({
  onLoad(options) {
    console.log(options.params) // { foo: 'bar' }
  }
})
復(fù)制代碼

就寫到這里吧,在使用原生方案開發(fā)的時候,這些技巧還是挺實用的。以后再寫寫怎樣構(gòu)建小程序,使小程序支持文件預(yù)編譯、require npm 包等。



易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://22321a.com/wxmini/doc/course/24670.html 復(fù)制鏈接 如需定制請聯(lián)系易優(yōu)客服咨詢:800182392 點擊咨詢
QQ在線咨詢