微信小程序 - 组件

组件通信事件

父传子

父组件如果需要向子组件传递指定属性的数据,在 WXML 中需要使用数据绑定的方式

与普通的 WXML 模板类似,使用数据绑定,这样就可以向子组件的属性传递动态数据。

父组件如果需要向子组件传递数据,只需要两个步骤:

  1. 在父组件 WXML 中使用 数据绑定 的方式向子组件传递动态数据

  2. 子组件内部使用 properties 接收父组件传递的数据即可

代码:

html 复制代码
<!-- 引用组件的页面模板 -->
<view>
  <costom prop-a="{{ name }}" prop-b="{{ age }}" />
</view>

在组件内部,需要在 Component 构造器中通过 properties 接收传递的数据,接收方式有两种:

js 复制代码
Component({
  /**
   * 组件的属性列表 props
   */
  properties: {
    propA: {
      type: String, // 传递的数据类型
      value: '' // 默认值
    },
    propB: Number // 简化的定义方式
  },

  // coding...
})

在子组件中也可以通过 this.setData()properties 中的数据进行修改,但是一般不建议修改

js 复制代码
// components/custom01/custom01.js
Component({

  /**
   * 组件的方法列表
   */
  methods: {
    // 修改列表中的数据
    updateProp () {
      this.setData({
        propB: this.properties.propB + 1
      })
    }
  }
})

子传父

子组件如果需要向父组件传递数据,可以通过小程序提供的事件系统实现传递传递,可以传递任意数据

事件系统是组件间通信的主要方式之一,自定义组件可以触发任意的事件,引用组件的页面可以监听这些事件,流程如下:

  1. 自定义组件触发事件时,需要使用 triggerEvent 方法发射一个自定义的事件
  2. 自定义组件标签上通过 bind 方法监听发射的事件

触发事件:

html 复制代码
<!-- 在自定义组件中 -->
<button type="primary" plain bindtap="sendData">传递数据</button>
js 复制代码
// components/custom05/custom05.js
Component({

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

  // 组件的方法列表
  methods: {

    // 将数据传递给父组件
    sendData () {

      // 如果需要将数据传递给父组件
      // 需要使用 triggerEvent 发射自定义事件
      // 第二个参数,是携带的参数
      this.triggerEvent('myevent', this.data.num)
      
    }

  }
})

监听事件:

html 复制代码
<view>{{ num }}</view>
<!-- 需要在自定义组件标签上通过 bind 方法绑定自定义事件,同时绑定事件处理函数 -->
<custom05 bind:myevent="getData" />
js 复制代码
Page({

  data: {
    num: ''
  },

  getData (event) {
    // 可以通过事件对象.detail 获取子组件传递给父组件的数据
    // console.log(event)
    this.setData({
      num: event.detail
    })
  }

})

数据监听器

数据监听器可以用于监听和响应任何属性和数据字段的变化,有时,需要在一些数据字段被 setData 设置时,需要执行一些操作。那么就可以使用 observers 数据监听器来实现。语法如下:

js 复制代码
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")

html 复制代码
<!-- 父组件 -->
<costom bind:myevent="getData" class="custom" />
<button bindtap="getChildComponent"></button>
js 复制代码
// 父组件
Page({
  data: {},
  getChildComponent: function () {
    const child = this.selectComponent('.custom')
    console.log(child)
  }
})

behaviors

小程序的 behaviors 方法是一种代码复用的方式,可以将一些通用的逻辑和方法提取出来,然后在多个组件中复用,从而减少代码冗余,提高代码的可维护性。

如果需要 behavior 复用代码,需要使用 Behavior() 方法,每个 behavior 可以包含一组属性、数据、生命周期函数和方法

组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用。

注册 behavior:

如果需要注册一个 behavior,需要借助 Behavior() 方法,接受一个 Object 类型的参数

js 复制代码
// my-behavior.js

module.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:

js 复制代码
// my-component.js
const myBehavior = require('my-behavior')

Component({
  behaviors: [myBehavior]
  
  // coding...
})

组件和它引用的 behavior 中可以包含同名的字段,对这些字段的处理方法如下:

  1. 如果有同名的属性或方法,采用 "就近原则",组件会覆盖 behavior 中的同名属性或方法

  2. 如果有同名的数据字段且都是对象类型,会进行对象合并,其余情况会 采用 "就近原则" 进行数据覆盖

  3. 生命周期函数和 observers 不会相互覆盖,会是在对应触发时机被逐个调用,也就是都会被执行

详细的规则:[同名字段的覆盖和组合规则](

组件 wxml 的 slot

在使用基础组件时,可以给组件传递子节点传递内容,从而将内容展示到页面中,自定义组件也可以接收子节点内容

只不过在组件模板中需要定义 <slot /> 节点,用于承载组件引用时提供的子节点

默认情况下,一个组件的 wxml 中只能有一个 slot 。需要使用多 slot 时,可以在组件 js 中声明启用。

同时需要给 slot 添加 name 来区分不同的 slot,给子节点内容添加 slot 属性来将节点插入到 对应的 slot 中

代码示例:

  • custom01.wxml
html 复制代码
<view>
  <slot name="slot-top" />
  <!-- slot 就是用来接收、承载子节点内容 -->
  <!-- slot 只是一个占位符,子节点内容会将 slot 进行替换 -->
  <!-- 默认插槽 -->
  <view><slot /></view>

  <slot name="slot-bottom" />
</view>
  • custom01.js
js 复制代码
// components/custom01/custom01.js

Component({

  options: {
    // 启用多 slot 支持
    multipleSlots: true
  }

})
  • cart.wxml
html 复制代码
<custom01>
  <text slot="slot-top">我需要显示到顶部</text>
    
  <!-- 默认情况下,自定义组件的子节点内容不会进行展示 -->
  <!-- 如果想内容进行展示,需要再组件模板中定义 slot 节点 -->
  我是子节点内容
    
  <text slot="slot-bottom">我需要显示到低部</text>
</custom01>
相关推荐
盛夏绽放5 小时前
微信小程序地图map全方位解析
微信小程序·小程序
初尘屿风7 小时前
基于微信小程序的电影院订票选座系统的设计与实现,SSM+Vue+毕业论文+开题报告+任务书+指导搭建视频
vue.js·微信小程序·小程序
paterWang9 小时前
基于SpringBoot的驾校报名小程序系统设计与实现(源码+文档)
spring boot·后端·小程序
EasyNVR10 小时前
EasyRTC:全平台支持与自研算法驱动的智能音视频通讯解决方案
运维·服务器·小程序·音视频·webrtc·p2p·智能硬件
韩召华15 小时前
微信小程序(uni)+蓝牙连接+Xprint打印机实现打印功能
微信小程序·小程序·notepad++
韩召华16 小时前
微信小程序实现拉卡拉支付
微信小程序·小程序
paterWang18 小时前
基于 Spring Boot + 微信小程序的短文写作竞赛管理系统设计与实现(源码+文档)
spring boot·后端·微信小程序
嘻哈∠※1 天前
基于SpringBoot+vue粮油商城小程序系统
vue.js·spring boot·小程序
luckyext1 天前
HBuilderX中,VUE生成随机数字,vue调用随机数函数
前端·javascript·vue.js·微信小程序·小程序
毕业设计-011 天前
0081.基于springboot+uni-app的垃圾分类小程序+论文
spring boot·小程序·uni-app