在 UniApp 开发中,掌握页面间通信的方法确实很重要。为了让你能快速了解和选择,下面这个表格汇总了常见的通信方式、核心方法和它们的典型适用场景。

🔀 UniApp页面通信方法一览

通信场景核心方法/工具关键要点适用场景
页面跳转传参uni.navigateTo 的 url 参数- 在onLoad生命周期中通过options参数接收。
- 参数长度需注意URL长度限制
正向传递简单数据,如用户ID到详情页。
反向传递数据getCurrentPages() 获取页面栈- 通过页面栈实例直接修改上一页的数据或调用方法。
灵活性高,但需注意页面栈的稳定性。
从B页面回传数据(如选择结果)到A页面。
全局状态管理Vuex (官方推荐)- 定义全局状态和修改函数。
- 各页面通过 mapStatemapMutations 等接入。
- 适合复杂应用的集中状态管理。
用户信息、全局主题等跨多个页面需要共享和响应的数据。
轻量级全局通信uni.$emit 和 uni.$on发布-订阅模式,可跨页面监听和触发事件。
- 注意在页面卸载时使用 uni.$off 移除监听,防止内存泄漏。
轻量级的跨页面事件通知,如登录状态更新。
本地持久化存储uni.setStorageSync- 数据会持久化到本地存储。
- 取数据用 uni.getStorageSync
需要持久化的数据,如用户登录凭证。
组件间通信props & 自定义事件- 父组件通过 props 传数据给子组件。
- 子组件通过 this.$emit 触发父组件事件。
父子组件之间的数据传递与行为交互。
Webview传参web-view 组件的 @message 事件- H5网页通过 uni.postMessage 发送数据。
- UniApp页面通过 @message 事件接收。
UniApp与内嵌H5页面之间的通信。

了解了各种方法的大致用途后,我们来看看其中几个关键方法的具体使用细节和代码示例。

💡 关键方法详解与代码示例

1. 页面跳转与传参

这是最基础的通信方式,用于页面跳转时传递数据。

  • 发送数据页面

javascript

// 跳转到 test 页面,并传递参数 id 和 name
uni.navigateTo({
  url: '/pages/test/test?id=1&name=UniApp'
});
  • 接收数据页面 (test.vue)
    在接收页面的 onLoad 生命周期函数中获取参数。

javascript

export default {
  onLoad(options) {
    // options 包含传入的参数对象
    console.log(options.id); // 输出 1
    console.log(options.name); // 输出 'UniApp'
    // 此处可以将参数赋值给页面的 data,用于界面显示
  }
}
2. 通过页面栈实现反向传参

当需要从B页面返回数据到A页面时,可以通过获取页面栈直接操作。

javascript

// 在B页面中,编写一个方法用于返回数据
sendDataBack() {
  // 获取页面栈实例数组
  const pages = getCurrentPages();
  // 获取上一个页面的实例(即A页面)
  const prevPage = pages[pages.length - 2];
  
  // 方式一:直接调用上一页的方法,并传入数据
  // 假设A页面有一个名为 receiveData 的方法
  prevPage.$vm.receiveData(this.backData);
  
  // 方式二:直接修改上一页的 data
  // prevPage.$vm.someData = this.backData;
  
  // 返回上一页
  uni.navigateBack();
}

注意:此方法依赖于页面栈结构,在复杂的导航流程中需谨慎处理。

3. 使用全局事件总线

对于跨多个页面的简单事件通知,全局事件总线非常方便。

  • 在B页面发送(发布)事件

javascript

// 假设用户信息更新了
uni.$emit('userInfoUpdated', { nickname: '新的用户名' });
  • 在A页面监听(订阅)事件

javascript

export default {
  onLoad() {
    // 监听事件,并在回调中执行操作
    uni.$on('userInfoUpdated', (data) => {
      console.log('收到用户信息更新:', data);
      this.userInfo = data; // 更新本页面的数据
    });
  },
  onUnload() {
    // 页面卸载时移除监听,避免内存泄漏
    uni.$off('userInfoUpdated');
  }
}
4. Vuex全局状态管理

对于复杂应用,Vuex能提供更规范、可预测的状态管理。

  • Store中定义状态与方法

javascript

// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 0,
    userInfo: null
  },
  mutations: {
    // 修改状态
    setUserInfo(state, info) {
      state.userInfo = info;
    },
    increment (state) {
      state.count++
    }
  },
  actions: {
    // 可处理异步操作
    fetchUserInfo({ commit }) {
      // ... 异步请求
      commit('setUserInfo', response.data);
    }
  }
})
  • 在页面中使用和修改状态

javascript

import { mapState, mapMutations } from 'vuex'

export default {
  computed: {
    // 将 store 中的 state 映射到当前组件的计算属性
    ...mapState(['count', 'userInfo'])
  },
  methods: {
    // 将 store 中的 mutations 映射到当前组件的 methods
    ...mapMutations(['increment', 'setUserInfo']),
    updateUser() {
      this.setUserInfo({ name: '张三' }); // 调用 mutation 更新状态
    }
  }
}

✅ 如何选择合适的通信方式

面对这么多方法,你可以根据以下思路进行选择:

  • 传递简单参数到下级页面:使用 页面跳转传参

  • 需要从下级页面返回数据(如选择城市、选择联系人):优先考虑使用 全局事件总线 (uni.$emit/uni.$on),或者通过 页面栈 直接修改。

  • 多个页面依赖同一份数据,且数据变化需要实时响应(如用户登录状态、主题颜色):使用 Vuex 进行全局状态管理。

  • 数据需要持久化到本地(如记住登录状态):使用 本地存储 (uni.setStorage)

  • 与内嵌H5页面通信:使用 web-view 组件的 @message 事件

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐