微信小程序 - 组件_微信小程序子组件获取父组件数据
组件通信事件
父传子
父组件如果需要向子组件传递指定属性的数据,在 WXML 中需要使用数据绑定的方式
与普通的 WXML 模板类似,使用数据绑定,这样就可以向子组件的属性传递动态数据。
父组件如果需要向子组件传递数据,只需要两个步骤:
-
在父组件 WXML 中使用 数据绑定 的方式向子组件传递动态数据
-
子组件内部使用 properties 接收父组件传递的数据即可
代码:
<view> <costom prop-a=\"{{ name }}\" prop-b=\"{{ age }}\" /></view>
在组件内部,需要在 Component 构造器中通过 properties 接收传递的数据,接收方式有两种:
Component({ /** * 组件的属性列表 props */ properties: { propA: { type: String, // 传递的数据类型 value: \'\' // 默认值 }, propB: Number // 简化的定义方式 }, // coding...})
在子组件中也可以通过 this.setData() 对 properties 中的数据进行修改,但是一般不建议修改
// components/custom01/custom01.jsComponent({ /** * 组件的方法列表 */ methods: { // 修改列表中的数据 updateProp () { this.setData({ propB: this.properties.propB + 1 }) } }})
子传父
子组件如果需要向父组件传递数据,可以通过小程序提供的事件系统实现传递传递,可以传递任意数据
事件系统是组件间通信的主要方式之一,自定义组件可以触发任意的事件,引用组件的页面可以监听这些事件,流程如下:
- 自定义组件触发事件时,需要使用
triggerEvent方法发射一个自定义的事件 - 自定义组件标签上通过 bind 方法监听发射的事件
触发事件:
<button type=\"primary\" plain bindtap=\"sendData\">传递数据</button>
// components/custom05/custom05.jsComponent({ // 组件的初始数据 data: { num: 666 }, // 组件的方法列表 methods: { // 将数据传递给父组件 sendData () { // 如果需要将数据传递给父组件 // 需要使用 triggerEvent 发射自定义事件 // 第二个参数,是携带的参数 this.triggerEvent(\'myevent\', this.data.num) } }})
监听事件:
<view>{{ num }}</view><custom05 bind:myevent=\"getData\" />
Page({ data: { num: \'\' }, getData (event) { // 可以通过事件对象.detail 获取子组件传递给父组件的数据 // console.log(event) this.setData({ num: event.detail }) }})
数据监听器
数据监听器可以用于监听和响应任何属性和数据字段的变化,有时,需要在一些数据字段被 setData 设置时,需要执行一些操作。那么就可以使用 observers 数据监听器来实现。语法如下:
Component({ data: { num: 10, count: 1, obj: { name: \'Tom\', age: 10 }, arr: [1, 2, 3] }, observers: { // key 是需要检测数据 // value 是一个函数,函数接收一个形参作为参数,是最新的值 num: function(newNum) { console.log(newNum) }, // 数据监听器支持监听属性或内部数据的变化,可以同时监听多个 \'num, count\': function (newNum, newCount) { console.log(newNum, newCount) } // 监听器可以监听子数据字段 \'obj.age\': function(newAge) { console.log(newAge) }, // 如果需要监听所有子数据字段的变化,可以使用通配符 ** \'obj.**\': function(newAge) { console.log(newAge) }, \'arr[0]\': function (val) {} }})
获取组件实例
如果前面两种方式不足以满足需要。
可在父组件里调用 this.selectComponent() ,获取子组件的实例对象,就可以直接拿到子组件的任意数据和方法。调用时需要传入一个匹配选择器 selector,如:this.selectComponent(\".my-component\")。
<costom bind:myevent=\"getData\" class=\"custom\" /><button bindtap=\"getChildComponent\"></button>
// 父组件Page({ data: {}, getChildComponent: function () { const child = this.selectComponent(\'.custom\') console.log(child) }})
behaviors
小程序的 behaviors 方法是一种代码复用的方式,可以将一些通用的逻辑和方法提取出来,然后在多个组件中复用,从而减少代码冗余,提高代码的可维护性。
如果需要 behavior 复用代码,需要使用 Behavior() 方法,每个 behavior 可以包含一组属性、数据、生命周期函数和方法
组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用。
注册 behavior:
如果需要注册一个 behavior,需要借助 Behavior() 方法,接受一个 Object 类型的参数
// my-behavior.jsmodule.exports = Behavior({ behaviors: [], properties: { myBehaviorProperty: { type: String } }, data: { myBehaviorData: \'my-behavior-data\' }, created: function () { console.log(\'[my-behavior] created\') }, attached: function () { console.log(\'[my-behavior] attached\') }, ready: function () { console.log(\'[my-behavior] ready\') }, methods: { myBehaviorMethod: function () { console.log(\'[my-behavior] log by myBehaviorMehtod\') }, }})
使用 behavior:
// my-component.jsconst myBehavior = require(\'my-behavior\')Component({ behaviors: [myBehavior] // coding...})
组件和它引用的 behavior 中可以包含同名的字段,对这些字段的处理方法如下:
-
如果有同名的属性或方法,采用 “就近原则”,组件会覆盖 behavior 中的同名属性或方法
-
如果有同名的数据字段且都是对象类型,会进行对象合并,其余情况会 采用 “就近原则” 进行数据覆盖
-
生命周期函数和 observers 不会相互覆盖,会是在对应触发时机被逐个调用,也就是都会被执行
详细的规则:[同名字段的覆盖和组合规则](
组件 wxml 的 slot
在使用基础组件时,可以给组件传递子节点传递内容,从而将内容展示到页面中,自定义组件也可以接收子节点内容
只不过在组件模板中需要定义 节点,用于承载组件引用时提供的子节点
默认情况下,一个组件的 wxml 中只能有一个 slot 。需要使用多 slot 时,可以在组件 js 中声明启用。
同时需要给 slot 添加 name 来区分不同的 slot,给子节点内容添加 slot 属性来将节点插入到 对应的 slot 中
代码示例:
- custom01.wxml
<view> <slot name=\"slot-top\" /> <view><slot /></view> <slot name=\"slot-bottom\" /></view>
- custom01.js
// components/custom01/custom01.jsComponent({ options: { // 启用多 slot 支持 multipleSlots: true }})
- cart.wxml
<custom01> <text slot=\"slot-top\">我需要显示到顶部</text> 我是子节点内容 <text slot=\"slot-bottom\">我需要显示到低部</text></custom01>


