小程序 · 2024 年 4 月 25 日 0

小程序 – 自定义组件

自定义组件

组件 wxml 的 slot

在组件的 wxml 中可以包含 slot 节点,用于承载组件使用者提供的 wxml 结构。

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

Component({
  options: {
    multipleSlots: true // 在组件定义时的选项中启用多slot支持
  },
  properties: { /* ... */ },
  methods: { /* ... */ }
})

此时,可以在这个组件的 wxml 中使用多个 slot ,以不同的 name 来区分。

<!-- 组件模板 -->
<view class="wrapper">
  <slot name="before"></slot>
  <view>这里是组件的内部细节</view>
  <slot name="after"></slot>
</view>

使用时,用 slot 属性来将节点插入到不同的 slot 上。

<!-- 组件模板 -->
<!-- 引用组件的页面模板 -->
<view>
  <component-tag-name>
    <!-- 这部分内容将被放置在组件 <slot name="before"> 的位置上 -->
    <view slot="before">这里是插入到组件slot name="before"中的内容</view>
    <!-- 这部分内容将被放置在组件 <slot name="after"> 的位置上 -->
    <view slot="after">这里是插入到组件slot name="after"中的内容</view>
  </component-tag-name>
</view>

输入框子传父案例

子组件:

  • 在子组件button上绑定 triggerHandle 点击事件

  • 将input输入框与data中的数据进行双向数据绑定

<view>
  <input type="text" class="text" model:value="{{inputContent}}"/>
  <button bind:tap="triggerHandle">传递给父组件</button>
</view>

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

  • button点击事件作用如下:

Component({
  data: {
    inputContent: '',// 接收input中的文本内容
  },
  methods: {
    triggerHandle(){
      // 1.触发父组件传递过来的自定义事件
      // 2.向父组件传递输入框中的内容 this.data.inputContent
      this.triggerEvent('MyEvent',{
        inputContent: this.data.inputContent
      })
    }
  }
})

父组件:

  • 自定义组件 item 上,绑定 MyEvent 自定义事件

  • 当子组件触发父组件传递过来的自定义事件时,执行 myEventHandle 方法

<item bindMyEvent="myEventHandle"></item>
<view>{{text}}</view>
  • myEventHandle方法:将子组件data中的inputContent给到父组件data中的text,同时呈现在父组件页面中

Page({
  data(){
    text: ""
  },
  // “e”为触发事件的相关信息,这里指代子组件传来的detail对象
  // 将子组件的inputContent值赋值给父组件data中的text
  myEventHandle(e){
    this.setData({
      text: e.detail.inputContent
    })
  }
})

组件之间涉及到数据的传递,和 Vue 是相似的,父传子通过 properties,子传父通过父组件的自定义事件来传递,注意在触发父组件的自定义事件是,使用的是 this.triggerEvent 来触发的。

可以通过 this.selectComponent(‘.自定义组件的样式类’) 来获取自定义组件实例对象

生命周期

在自定义组件中,提供了

  • created:组件实例刚刚被创建好时。此时,组件数据 this.data 就是在 Component 构造器中定义的数据 data此时还不能调用 setData通常情况下,这个生命周期只应该用于给组件 this 添加一些自定义属性字段。有点类似于 Vue 里面的 created

  • attached:在组件完全初始化完毕、进入页面节点树后, attached 生命周期被触发。此时, this.data 已被初始化为组件的当前值。这个生命周期很有用,绝大多数初始化工作可以在这个时机进行。有点类似于 Vue 里面的 mounted

  • detached:在组件离开页面节点树后触发,类似于 Vue 里面的 destory

behaviors

这个就类似于 Vue 里面的 mixin,用来提取组件公共的部分(data、method、生命周期钩子)

当我们要定义一个 behavior 的时候,需要用到 Behavior 构造器

// 模块导出
module.exports = Behavior({
  properties: {},
  data: {},
  lifetimes: {},
  methods: {}
})

// 引用 behaviors 定义段
const myBehavior = require("../../behaviors/myBehavior.js")

组件间关系

在使用 relations 的时候,必须两个关联的组件都要加入此字段。

组件使用 relations 设定了相互关系后,最大的好处在于能和关联的组件进行通信,如何通信呢?

主要就是拿到关联组件的实例对象,实例对象一拿到,data数据也就拿到了。

数据监听器

数据监听器可以用于监听和响应任何属性和数据字段的变化。从小程序基础库版本 2.6.1 开始支持。

这个和 Vue 中的 watch 非常相似。

纯数据字段

有一些情况下,某些 data 中的字段(包括 setData 设置的字段),既不会展示在页面,也不会传递给其他组件,仅仅在当前组件内部使用。

此时,可以指定这样的数据为”纯数据字段”。它们将仅仅被记录在 this.data 中,而不参与任何界面渲染过程,这样有助于提升页面更新性能。

  1. 首次,在 Component 中的 options 指定一个正则表达式

  2. 在 data 中所定义的数据能够匹配上该正则,那么该数据字段就是一个纯数据字段

  3. 纯数据字段值发生变化时,不会引起页面的重新渲染

抽象节点

这个类似于 react 的 renderProps,抽象节点的核心就是在使用自定义组件时,可以将另一个组件以 props 的形式传递到该自定义组件中。因此传递的是什么组件,最终渲染的就是什么组件。

首先第一步,我们在使用自定义组件时,可以将另外的自定义组件像 props 一样传入

<item4 generic:selectable="sel1"/>
<item4 generic:selectable="sel2"/>

在上面的代码中,我们使用了 item4 这个自定义组件,然后我们还分别将 sel1、sel2 作为 props 传入到 item4 里面。

注意这里需要在对应的 json 文件中注册 sel1、sel2、item4 这几个组件。

接下来在 item4 这个自定义组件中,书写 selectable 来渲染传入的自定义组件

<view class="container">
  <text>item4</text>
  <view>该示例演示了抽象节点</view>
  <selectable/>
</view>

另外,在接受渲染组件的自定义组件中(item4)的 json 文件中,需要开启 selectable

{
  "componentGenerics": {
    "selectable": true
  }
}

抽象节点和插槽非常类似?

这个抽象节点和 react 的 renderProps 非常相似,主要作用是用来横向抽离公共的逻辑,因为我们是传入的一个组件,组件里面是一套完整的功能。之后我们可以将一些公共的逻辑(视图、数据、行为)单独的以组件的形式抽离出来。

 

参考文档地址:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/