微信小程序-自定义组件及组件之间的通信

小程序自定义组件

官方文档:
组件的说明:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/
事件的说明:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html
Component详解:https://developers.weixin.qq.com/miniprogram/dev/reference/api/Component.html

开发者可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。自定义组件在使用时与基础组件非常相似。

在微信小程序中,页面page也可以看成一个组件。

小程序中组件的通信与事件

父组件像子组件传递数据

WXML 数据绑定:用于父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容数据(自基础库版本 2.0.9 开始,还可以在数据中包含函数)。具体在 组件模板和样式 章节中介绍。

父组件向子组件发送数据

父(外部)组件向子(内)组件传递数据是通过在子组件上自定义属性的方式实现的。

<count num="{{countNum}}" bind:changeCount="handleCount"></count>

示例中,num是子组件自定义属性,countNum是父组件的数据。

子组件接收父组件发送的数据

子组件的properties对象接收外部(父)组件传过来的自定义属性数据。

// components/count/count.js
Component({
  /* 组件的属性列表 */
  properties: {
    num: Number, // 在这里接收外部组件传递过来的属性,同时确定传递过来数据的类型,类型有String,Boolean,Object,Array等
  },

  /* 组件的初始数据 */
  data: {},

  /* 组件的方法列表 */
  methods: {},
});

那么在内部组件中如何渲染呢,直接将properties下的变量对象与wxml中通过{{}}插值表达式进行绑定关联就可以了。

子组件向父组件传递数据

事件:用于子组件向父组件传递数据,可以传递任意数据。

父组件接收子组件传过来的数据

<count num="{{countNum}}" bind:changeCount="handleCount"></count>

示例中父组件在调用子组件时bind:changeCount="handleCount"是绑定自定义事件,事件名changeCount,事件响应方法handleCount

Page({
  // 注意,这里Page的事件处理函数不是写在methods对象中。
  handleCount: function(event) {
    event.detail; // 自定义组件触发事件时提供的detail对象,子组件传给父组件的数据就在这里
  },
});

子组件向父组件发送数据(触发事件)

子组件中,自定义组件触发事件时,需要使用 triggerEvent 方法,指定事件名、detail对象和事件选项。

<!-- 在自定义组件中 -->
<button bind:tap="onTap">点击这个按钮将触发“changeCount”事件</button>
Component({
  properties: {},
  methods: {
    onTap: function(){
      var myEventDetail = {"countNum": 22} // detail对象,提供给事件监听函数
      var myEventOption = {} // 触发事件的选项
      this.triggerEvent('changeCount', myEventDetail, myEventOption)
    }
  }
})

这个过程虽然有些绕,但细心梳理一下就应该明白。相当于在组件中,点击了按钮,调用了父组件的方法。

父组件通过 this.selectComponent 方法获取子组件数据

如果以上两种方式不足以满足需要,父组件还可以通过 this.selectComponent 方法获取子组件实例对象,这样就可以直接访问组件的任意数据和方法。

<count class="countcls" num="{{countNum}}" bind:changeCount="handleCount"></count>

使用前提条件添加class或id

var count = this.selectComponent('.countcls');

其他扩展知识

小程序中data与properties有何异同?

  • data更倾向于存储组件的私有数据,外部不能访问。
  • properties更倾向于储存外界传递到组件中的数据,外部可以访问。
  • date和properties都可以在组件中使用{{}}访问到。
  • 不管使用this.data与this.properties都可以相互访问。只不过有时properties中的类型可能不一样。

如果都定义了 this.data.aaa与this.properties.aaa,我们会发现其值会相互覆盖。也就是properties和data经过编译后会进行合并。
我们不要把data和properties里的变量设置成同一个名字,如果他们名字相同,properties里的会覆盖data里的。

自定义组件中更改data的级别(级别高的会覆盖级别低的)

this.setData({index: 123}) # 会同时修改 this.properties.index和this.data.index,并将其值渲染到页面中
properties: {index: 456} # 会同时修改 this.properties.index和this.data.index
data: {index: 'abc'} # 只会修改 this.data中的值

小程序Page事件处理方法,与Component的methods中的事件处理方法有何不同?

  • methods 组件的方法,在Component中才有此属性。
  • 在Page页面中,是没有定义methods的,直接自定义函数即可,最好使用on开头。

此处评论已关闭