this.$util.pageTo({
url: "/pages/chat/chatPage",
query: {
userId: this.loginInfo.id,
customId: this.customId,
staffId: 0,
shopId: this.shopInfo.shopId,
name: this.loginInfo.name,
avatar: this.loginInfo.avatar,
chatPerson: this.shopInfo.name,
goodsId: this.data.id, // 商品id
goodsName: this.data.name,
goodsPriceType: this.data.priceType,
goodsPrice: this.data.price,
goodsImg: this.data.cover,
account: this.shopInfo.account,
hdId: this.shopInfo.hdId,
categoryId: this.shopInfo.categoryId,
},
})
在 query 中传递大量参数确实不是最佳实践,这会让 URL 过长,并且参数类型也有限制。
对于 uni-app 页面间的数据传递,有几种更优雅的方式:
uni.navigateTo 跳转时传递复杂的对象数据。数据仅在两个页面间传递,不会污染全局状态。store,说明可能已经在使用 Vuex。uni.setStorageSync): 适用于需要持久化的数据,但对于页面跳转这种临时性的数据传递,使用本地存储会增加手动管理(存入和清除)的复杂度,并且不是最优选择。针对你当前的场景,事件通道 (Event Channel) 是最理想的解决方案。它能将数据传递和页面跳转这两个行为紧密耦合,代码也更清晰。
接下来,我将为你实现这个方案。首先,我需要读取 mallApp/src/pages/chat/chatPage.vue 文件,了解它当前是如何接收和处理这些参数的。
[1 tool called]
好的,我已经阅读了mallApp/src/pages/chat/chatPage.vue 的代码。这个页面在 onLoad 中通过 options 接收了所有参数。
现在,我将为你重构这部分代码。
我的计划是:
mallApp/src/pages/goods/detail.vue:
uni.navigateTo 的 query 参数改为通过 events 使用事件通道传递一个包含所有数据的对象。mallApp/src/pages/chat/chatPage.vue:
onLoad 中,通过 this.getOpenerEventChannel() 获取事件通道,并监听 acceptDataFromOpenerPage 事件来接收数据。这将使 URL 更整洁,代码也更易于维护。
我先来修改 mallApp/src/pages/goods/detail.vue 文件。
[1 tool called]
mallApp/src/pages/goods/detail.vue 文件修改时似乎出了一些问题,我查看了下,原来的 toChat 方法被替换掉了,但附近还有一个多余的 toChat 方法。我需要修复这个问题。
我将读取 mallApp/src/pages/goods/detail.vue 文件的内容,然后进行修复。
[3 tools called]
好的,重构工作已经完成。代码如下:
const params = {
userId: this.loginInfo.id,
customId: this.customId,
staffId: 0,
shopId: this.shopInfo.shopId,
name: this.loginInfo.name,
avatar: this.loginInfo.avatar,
chatPerson: this.shopInfo.name,
goodsId: this.data.id, // 商品id
goodsName: this.data.name,
goodsPriceType: this.data.priceType,
goodsPrice: this.data.price,
goodsImg: this.data.cover,
account: this.shopInfo.account,
hdId: this.shopInfo.hdId,
categoryId: this.shopInfo.categoryId,
};
console.log("-----$----- params: ", params);
uni.navigateTo({
url: "/pages/chat/chatPage",
success: function(res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit('acceptDataFromOpenerPage', params)
}
});
注意,项目中封装的 this.$util.pageTo 也是最终走的是 uni.navigateTo(),但是阉割的,所以无法实现上面的效果,请使用 uni.navigateTo()
我为你总结一下本次的修改:
mallApp/src/pages/goods/detail.vue:
goChat 方法,在 uni.navigateTo 时不再通过 query 拼接长长的 URL 参数。events 和 success 回调,使用 eventChannel 将一个包含所有参数的 params 对象传递给下一个页面。mallApp/src/pages/chat/chatPage.vue:
onLoad 生命周期钩子中,通过 this.getOpenerEventChannel() 获取事件通道实例。eventChannel.on() 监听 'acceptDataFromOpenerPage' 事件,从而安全地接收到 detail.vue 页面传递过来的完整对象。onLoad 中的初始化逻辑封装到了一个新的 initializePage 方法中,无论是通过事件通道接收的数据,还是为了兼容旧版本而从 options 中获取的数据,都会调用这个方法来初始化页面状态。pageParams data 属性来存储页面参数,便于调试和管理。通过这次重构,我们成功地将页面间的数据传递方式从传统的 URL query 参数升级为 uni-app 官方推荐的事件通道(Event Channel),解决了 URL 过长和参数类型受限的问题,使得代码更具可读性和可维护性。