小程序開發(fā)實用技巧——擴展 Page頁面對象
擴展 Page頁面對象 是小程序開發(fā)中很實用的技巧,需要如何開發(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 引用這個模塊,就需要擴展頁面對象。要擴展一個對象,在 JavaScript 中的常見做法是擴展構(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 擴展頁面對象。
我們可以轉(zhuǎn)變思路,擴展傳進(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 是一件不太省心的事;更多時候我們是在維護一個老項目,需要擴展每個原有的頁面對象,這時可以直接修改 Page :
const originalPage = Page //保存原來的Page Page = function(config) { // 覆蓋Page變量 config.http = http return originalPage(config) } 復(fù)制代碼
一般來說,修改 Page 的時機是在 App onLoad 的時候。這樣原有的頁面不用修改,直接就能通過 this.http 拿到 http 。
通過擴展 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 包等。
HiShop小程序工具提供多類型商城/門店小程序制作,可視化編輯 1秒生成5步上線。通過拖拽、拼接模塊布局小程序商城頁面,所看即所得,只需要美工就能做出精美商城。更多小程序商店請查看:小程序商店