前言
小程序开发场景中,经常会遇到页面之间传递数据,页面通信,派发通知更新数据等业务场景,经过多次的业务迭代和各种业务场景的实现,终于找到了最佳的的实现方案,当然可能是我认为的最佳方案,记录一波方便大家对比和参考。
第一种场景
存储用户信息、设备信息、全局标记信息等
// app.js
App({
globalData: {
// 众多属性
},
});
页面获取、存储、更改
// index.js
const { globalData } = getApp();
console.log(globalData);
Page({
add() {
globalData.userInfo = { uid: 123456 };
},
});
通过以上方式,可以在任何页面获取 globalData 进行修改和存储内容
第二种方式
路由跳转传递参数,适用于页面和页面之间传递参数通信
// index.js
Page({
jump() {
wx.navigateTo({
url: "test?id=1",
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromOpenedPage: function (data) {
console.log(data);
},
someEvent: function (data) {
console.log(data);
},
},
success: function (res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit("acceptDataFromOpenerPage", { data: "test" });
},
});
},
});
//test.js
Page({
onLoad: function (option) {
console.log(option.query);
const eventChannel = this.getOpenerEventChannel();
eventChannel.emit("acceptDataFromOpenedPage", { data: "test" });
eventChannel.emit("someEvent", { data: "test" });
// 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
eventChannel.on("acceptDataFromOpenerPage", function (data) {
console.log(data);
});
},
});
以上方式通过路由跳转的传递某些关键参数,但是通过wx.navigateTo的events属性可以进行数据的大量传递以及两个页面之间的通信。
第三种方式
通过 getCurrentPages 方法进行获取路由信息进行调用、获取、更新数据等。
//index.js
Page({
add(){
const testPageInfo = getCurrentPages().find(item => item.route === 'pages/test/index')
// 获取到指定页面的路由信息,通过对当前路由信息进行调用、获取、更新数据等。
// 更新某些属性
testPageInfo.setData({a: 1})
// 调用某些方法
testPageInfo.change()
}
});
第四种方式
通过订阅发布者模式进行通信和派发通知等
// utils/index.js
/**
* eventBus 事件总线
*/
export const eventBus = {
clients: {},
/**
* @method addEventListener 事件监听
* @param {'onLoginSucess'} method 方法名
* @param {Function} fn 回调函数
*/
addEventListener(method, fn) {
if (!this.clients[method]) {
this.clients[method] = [];
}
this.clients[method].push(fn);
},
/**
* @method triggerEventListener 事件触发
* @param {'onLoginSucess'} method 方法名
* @param {object} data
*/
triggerEventListener(method, data) {
if (!this.clients[method]) {
log &&
console.log(
`========================👇 触发 eventBus 事件错误, 不存在或未注册${method}方法 👇========================\n\n`
);
}
this.clients[method]?.forEach((fn) => fn(data));
},
/**
* @method removeEventListener 删除事件
* @param {'onLoginSucess'} method 方法名
*/
removeEventListener(method) {
if (!this.clients[method]) {
log &&
console.log(
`========================👇 触发 eventBus 事件错误, 不存在或未注册${method}方法 👇========================\n\n`
);
}
this.clients[method]?.pop();
},
};
// pages/login/index.js
import { eventBus } from '~/utils/index';
Page({
/**
* 页面的初始数据
*/
data: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
eventBus.addEventListener("onLoginSucess", (data) => {});
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
eventBus.removeEventListener("onLoginSucess");
},
});
// pages/test/index.js
import { eventBus } from '~/utils/index';
Page({
/**
* 页面的初始数据
*/
data: {},
test(options) {
eventBus.triggerEventListener({test: '123'});
}
});
通过上述方式可以一次性和多个页面进行派发通知和通信交互,后续的业务场景中经常使用上述方式。
当然以上四种方式都是业务开发中常用的处理方案,具体使用哪种也要根据具体的业务逻辑来选择。如果你有更好的方式请在评论区告诉我。