微信小程序中頁面間的通信是指不同頁面之間的數據傳遞、狀態同步或交互操作,常見于多頁面協作場景。根據通信方向和場景不同,主要有以下幾種實現方式:
一、基于頁面跳轉的參數傳遞
1. 正向傳遞(A頁面到B頁面)
通過URL參數攜帶數據,在跳轉時傳遞給目標頁面,適用于簡單數據的一次性傳遞。
// A頁面跳轉代碼(聲明式導航) <navigator url="/pages/B/B?id=100&name=測試">跳轉到B頁面</navigator>// A頁面跳轉代碼(編程式導航) wx.navigateTo({url: '/pages/B/B?id=100&name=測試' })// B頁面接收參數(在onLoad生命周期中) Page({onLoad(options) {console.log(options.id); // 100console.log(options.name); // 測試} })
注意:參數值需避免特殊字符,若包含中文或特殊符號,建議使用encodeURIComponent編碼后傳遞。
2. 反向傳遞(B頁面到A頁面)
從子頁面返回父頁面時,通過頁面棧獲取父頁面實例,直接調用其方法傳遞數據。
// B頁面返回并傳遞數據 Page({backToA() {// 獲取當前頁面棧const pages = getCurrentPages();// 上一頁(A頁面)實例const prevPage = pages[pages.length - 2];// 調用A頁面的方法傳遞數據prevPage.receiveData('從B頁面返回的數據');// 返回上一頁wx.navigateBack();} })// A頁面定義接收數據的方法 Page({data: {dataFromB: ''},receiveData(data) {this.setData({dataFromB: data});} })
適用于表單提交后刷新列表、選擇器返回選擇結果等場景。
二、全局數據共享機制
1. 全局變量(app.js)
在app.js中定義全局數據,所有頁面通過getApp()訪問,適合簡單的全局狀態共享。
// app.js中定義 App({globalData: {userInfo: null,theme: 'light'} })// 頁面中訪問和修改 const app = getApp(); // 讀取 console.log(app.globalData.theme); // 修改 app.globalData.theme = 'dark';
缺點:數據變化時不會自動通知頁面更新,需手動調用setData刷新視圖。
2. 狀態管理庫(如mobx-miniprogram)
通過響應式狀態管理庫實現跨頁面數據同步,適合中大型項目。
// 1. 定義store(store/index.js) import { observable, action } from 'mobx-miniprogram'; export const store = observable({count: 0,updateCount: action(function(val) {this.count = val;}) });// 2. 頁面A中修改狀態 import { store } from '../../store'; store.updateCount(10);// 3. 頁面B中監聽狀態變化 import { createStoreBindings } from 'mobx-miniprogram-bindings'; Page({onLoad() {this.bindings = createStoreBindings(this, {store,fields: ['count'],actions: ['updateCount']});},onUnload() {this.bindings.destroy();} })
特點:數據變化時自動更新所有引用頁面,實現真正的響應式通信。
三、本地緩存通信
利用小程序的本地緩存API(同步/異步)存儲數據,實現跨頁面共享,數據可持久化。
// 存儲數據(頁面A) wx.setStorageSync('userToken', 'abc123'); wx.setStorage({key: 'userInfo',data: { name: '張三' },success() { console.log('存儲成功') } });// 讀取數據(頁面B) const token = wx.getStorageSync('userToken'); wx.getStorage({key: 'userInfo',success(res) { console.log(res.data.name) } // 張三 });
適用場景:存儲登錄憑證、用戶偏好設置等需長期保留的數據,注意緩存有大小限制(約10MB)。
四、事件總線(EventBus)
通過自定義事件總線實現任意頁面間的通信,適合無直接跳轉關系的頁面。
// 1. 創建事件總線(utils/eventBus.js) class EventBus {constructor() {this.events = {};}// 訂閱事件on(name, callback) {if (!this.events[name]) this.events[name] = [];this.events[name].push(callback);}// 發布事件emit(name, data) {if (this.events[name]) {this.events[name].forEach(cb => cb(data));}}// 取消訂閱off(name, callback) {if (this.events[name]) {this.events[name] = this.events[name].filter(cb => cb !== callback);}} } export default new EventBus();// 2. 頁面A訂閱事件 import eventBus from '../../utils/eventBus'; Page({onLoad() {this.handleMsg = (data) => {console.log('收到消息:', data);};eventBus.on('msgEvent', this.handleMsg);},onUnload() {eventBus.off('msgEvent', this.handleMsg); // 頁面卸載時取消訂閱} })// 3. 頁面B發布事件 import eventBus from '../../utils/eventBus'; Page({sendMsg() {eventBus.emit('msgEvent', '來自B頁面的消息');} })
優點:解耦性強,適合復雜頁面結構的通信;需注意及時取消訂閱避免內存泄漏。
五、各方式適用場景對比
URL參數傳遞:適合簡單數據的正向跳轉,如詳情頁ID傳遞。
頁面棧反向傳遞:適合子頁面返回父頁面時傳遞結果,如選擇器組件。
全局變量:適合簡單的全局數據共享,如應用配置。
狀態管理庫:適合中大型項目的復雜狀態同步,如購物車數據。
本地緩存:適合持久化數據存儲,如登錄狀態、用戶設置。
事件總線:適合無直接關聯頁面的通信,如跨模塊通知。
實際開發中,可根據項目復雜度和具體場景選擇合適的方式,復雜場景下可組合多種方式使用。