页面之间传递数据问题.md 5.3 KB

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 页面间的数据传递,有几种更优雅的方式:

  1. 事件通道 (Event Channel): 这是 uni-app 官方推荐的页面间通信方式,非常适合在 uni.navigateTo 跳转时传递复杂的对象数据。数据仅在两个页面间传递,不会污染全局状态。
  2. Vuex: 如果这些数据是全局状态的一部分,或者多个页面都需要共享,使用 Vuex 会是更规范、更易于管理的选择。从项目结构看,你的项目中已经引入了 store,说明可能已经在使用 Vuex。
  3. 本地存储 (uni.setStorageSync): 适用于需要持久化的数据,但对于页面跳转这种临时性的数据传递,使用本地存储会增加手动管理(存入和清除)的复杂度,并且不是最优选择。

针对你当前的场景,事件通道 (Event Channel) 是最理想的解决方案。它能将数据传递和页面跳转这两个行为紧密耦合,代码也更清晰。

接下来,我将为你实现这个方案。首先,我需要读取 mallApp/src/pages/chat/chatPage.vue 文件,了解它当前是如何接收和处理这些参数的。

[1 tool called]

好的,我已经阅读了 mallApp/src/pages/chat/chatPage.vue 的代码。这个页面在 onLoad 中通过 options 接收了所有参数。

现在,我将为你重构这部分代码。

我的计划是:

  1. 修改 mallApp/src/pages/goods/detail.vue:
    • uni.navigateToquery 参数改为通过 events 使用事件通道传递一个包含所有数据的对象。
  2. 修改 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()

我为你总结一下本次的修改:

  1. mallApp/src/pages/goods/detail.vue:

    • 修改了 goChat 方法,在 uni.navigateTo 时不再通过 query 拼接长长的 URL 参数。
    • 取而代之的是,通过 eventssuccess 回调,使用 eventChannel 将一个包含所有参数的 params 对象传递给下一个页面。
  2. 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 过长和参数类型受限的问题,使得代码更具可读性和可维护性。