组件间通信与事件

组件间通信

组件间的基本通信方式有以下几种:

  • 在父组件中可以通过设置子组件的properties来向子组件传递数据;
  • 在父组件中定义messages对象,对子组件dispatch方法进行拦截,从而达到子组件向上通信;
  • 子组件可以通过triggerEvent方法触发父组件的自定义事件进行传参;
  • 如果以上几种方式不足以满足需要,父组件还可以通过 this.selectComponent 方法获取子组件实例对象,这样就可以直接访问组件的任意数据和方法。

监听事件

解释:事件系统是组件间通信的主要方式之一。自定义组件可以触发任意的事件,引用组件的页面可以监听这些事件。监听自定义组件事件的方法与监听基础组件事件的方法完全一致:

代码示例

  1. <!-- 父组件模板 -->
  2. <component-tag-name bindmyevent="onMyEvent" />

通过dispatch方法与父组件通信

通过 dispatch 方法,子组件可以向组件树的上层派发消息。消息将沿着组件树向上传递,直到遇到第一个处理该消息的组件,则停止。通过 messages 可以声明组件要处理的消息,messages 是一个对象,key 是消息名称,value 是消息处理的函数,接收一个包含 target(派发消息的组件) 和 value(消息的值) 的参数对象。

代码示例在开发者工具中预览效果

  1. /* 父组件逻辑 */
  2. Component({
  3. messages: {
  4. 'childmessage': function (e) {
  5. console.log('childmessage', e);
  6. }
  7. }
  8. });
  1. /* 子组件逻辑 */
  2. Component({
  3. created() {
  4. this.dispatch('childmessage', {
  5. name: 'swan'
  6. });
  7. }
  8. });

通过triggerEvent方法与父组件通信

解释:自定义组件触发事件时,需要使用 triggerEvent 方法,指定事件名和detail对象:

  1. <button bindtap="onTap">点击这个按钮将触发 myevent 事件</button>

代码示例

在开发者工具中预览效果

  1. /* 组件child页面 */
  2. <button bindtap="onTap">点击这个按钮将触发 myevent 事件</button>
  1. /* 组件child逻辑 */
  2. Component({
  3. properties: {},
  4. methods: {
  5. onTap: function() {
  6. var myEventDetail = {} // detail对象,提供给事件监听函数
  7. var myEventOption = {bubbles:true} // 触发事件的选项
  8. this.triggerEvent('myevent', myEventDetail,myEventOption);
  9. }
  10. }
  11. });
  1. /* 使用该组件的页面 */
  2. <child bindmyevent="listener"></child>
  1. /* 使用该组件的逻辑 */
  2. Page({
  3. listener: function (e) {
  4. console.log(e);
  5. }
  6. })

触发事件的选项包括:

选项名类型是否必填默认值描述
bubblesBooleanfalse事件是否冒泡
capturePhaseBolleanfalse事件是否拥有捕获阶段

关于自定义组件的冒泡和捕获阶段。

代码示例

  1. <!-- 页面 index.swan -->
  2. <parent bindcustomevent="pageEventListener1">
  3. <child bindcustomevent="pageEventListener2"></child>
  4. </parent>
  1. <!-- 组件 parent.swan -->
  2. <view bindcustomevent="anotherEventListener">
  3. <slot />
  4. </view>
  1. <!-- 组件 child.swan -->
  2. <view bindcustomevent="myEventListener">
  3. <button bindtap="onTap">点我触发</button>
  4. </view>
  1. // 组件 child.js
  2. Component({
  3. methods: {
  4. onTap: function(){
  5. this.triggerEvent('customevent', {}) // 只会触发 pageEventListener2
  6. // this.triggerEvent('customevent', {}, { bubbles: true }) // 会依次触发 pageEventListener2 、 pageEventListener1
  7. // this.triggerEvent('customevent', {}, { bubbles: true, capturePhase: true }) // 会依次触发 pageEventListener2 、 anotherEventListener 、 pageEventListener1
  8. }
  9. }
  10. })

注意

  • 对于 triggerEvent 方法,在基础库版本 2.0.3 之前(不包含2.0.3)只支持传递类型为object的数据,从 2.0.3 开始支持传递其它数据类型(不包括function和undefined),其它低版本请做好兼容
  • 对于很多UI组件库需要实现组件间关系,实际上组件间通信同样可以满足此需求。(之前组件间通信无法在存在 slot 环境使用,我们将于基础版本库 3.110.14 修复此问题)详细内容组件间通信与事件 - 图1
  • 通过triggerEvent方式触发的自定义事件,只能在拥有父子关系的组件之间传播。
  • 只能触发绑定在组件自身标签上的事件监听方法。