微信小程序:自定义组件

272 阅读7分钟

自定义组件

关于自定义组件:developers.weixin.qq.com/miniprogram…

在使用自定义组件的时候,首先需要注意版本问题,基础库要大于等于 1.6.3

在使用自定义组件的时候,一般单独拿一个目录来存放自定义组件,一般是 components

页面中在使用自定义组件时,需要在在 json 文件中进行一个配置,例如:

{
  "usingComponents": {
    "item" : "/components/item/item"
  }
}

从开发者工具 1.02.1810190 及以上版本开始,可以在 app.json 中使用 usingComponents 来注册组件,在 app.json 中所注册的组件被视为全局组件,各个页面,以及其他自定义组件中都可以使用。

 // app.json
 "usingComponents": {
    "icons": "/components/icon"
  }

在设计自定义组件的时候,是可以添加插槽,插槽的用法和 Vue 是非常类似的。

并且和 Vue 中的插槽一样,可以设置具名插槽

注意:使用具名插槽时需要在options中添加multipleSlots: true,且无法像vue一样添加插槽默认内容<slot>默认内容</slot>

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

定义插槽:

<view class="container">
  <slot name="before"></slot>
  <slot></slot>
  <slot name="after"></slot>
</view>

使用自定义组件时,就可以往插槽插入动态的内容

<view class="container">
    <view slot="before">这部分内容会被放入到before</view>
    <view slot="after">这部分内容会被放入到after</view>
    <view>这部分内容会被放入到默认插槽</view>
</view>

Component 构造器

  • App:整个小程序的构造器
  • Page:页面对应的构造器
  • Component:自定义组件构造器
    • properties:在使用自定义组件时,父组件传入的属性
    • data:表示该自定义组件自身的数据
    • methods:书写对应的事件处理函数
    • options: 关于自定义组件的选项配置,例如我们要使用多插槽的时候,就需要配置 multipleSlots 为 true
    • externalClasses:用于指定外部传入的样式类
    • lifetimes:生命周期钩子函数,早期的时候,生命周期钩子函数和 Page、App 一样,直接写在配置对象里面,但是后面随着版本的更新,现在推荐写在 lifetimes 配置对象里面,并且写在 lifetimes 里面的优先级是最高的。
    • pageLifetimes:组件所在页面的生命周期

实际上,页面也可以被当作是一个自定义组件来使用。

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

可以通过 this.selectComponent('.自定义组件的样式类') 示例:this.selectComponent('.icons-class')来获取自定义组件实例对象

生命周期

在自定义组件的lifetimes中,提供了

  • created:组件实例刚刚被创建好时,**此时还不能调用 setData 。**通常情况下,这个生命周期只应该用于给组件 this 添加一些自定义属性字段。有点类似于 Vue 里面的 created
  • attached:在组件完全初始化完毕、进入页面节点树后, attached 生命周期被触发,这个生命周期很有用,绝大多数初始化工作可以在这个时机进行。有点类似于 Vue 里面的 mounted
  • detached:在组件离开页面节点树后触发,类似于 Vue 里面的 destory

behaviors

behaviors 是用于组件间代码共享的特性,类似于一些编程语言中的 “mixins” 或 “traits”。其实也能用在Page构造函数内

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

注意:与Component构造器配置一致

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

  1. 定义公共部分

image.png

  1. 要用到的地方

image.png

组件间关系

在使用自定义组件的时候,可以使用 relations 字段来指定自定义组件之间的关系,指定了关系之后,就可以获取到对应组件的实例。

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

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

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

数据监听器

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

这个实际上就和 Vue 里面的 watch 是类似的。

Component({
  attached: function() {
    this.setData({
      numberA: 1,
      numberB: 2,
    })
  },
  observers: {
    'numberA, numberB': function(numberA, numberB) {
      // 在 numberA 或者 numberB 被设置时,执行这个函数
      this.setData({
        sum: numberA + numberB
      })
    }
  }
})

纯数据字段

在 data 里面所定义的数据,一般来讲在页面是会重新渲染的。如果有一些数据,既不会展示在界面上,也不会传递给其他组件,仅仅是拿来做数据计算的,那么这个时候如果定义在 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">
  <view>item4</view>
  <view>该示例演示了抽象节点</view>
  <selectable/>
</view>

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

"componentGenerics": {
  "selectable": true
}

这玩意儿和插槽非常类似?

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

使用第三方组件库

微信小程序的组件库也是非常丰富的,比较有名的:

微信官方也提供了一套官方的组件,叫做 WeUI,但是风格基本上就和微信非常相似

vant 使用示例

  1. 安装
// 通过 yarn 安装 
yarn add @vant/weapp --production

但是在安装之前,需要先使用 npm init -y 初始化一下整个项目

  1. 去掉 app.json 里面的 "style": "v2",否则可能会出现样式混乱

新版的微信开发者工具不需要修改 project.config.json,所以我们直接进入到第四步,点击【工具】下面的【构建npm】,完成构建

image-20230202091459194

构建成功之后,根目录下面会生成 miniprogram_npm 目录

image-20230202091642411

使用组件时,需要现在页面的 json 中进行配置,例如:

{
  "usingComponents": {
    "van-button": "@vant/weapp/button/index",
  }
}