Skip to content

小程序组件化开发

组件化开发

小程序在刚刚推出时是不支持组件化的, 也是为人诟病的一个点:

  • 但是从 v1.6.3 开始, 小程序开始支持自定义组件开发, 也让我们更加方便的在程序中使用组件化

image-20231007165711916

组件化思想的应用:

  • 有了组件化的思想,我们在之后的开发中就要充分的利用它
  • 尽可能的将页面拆分成一个个小的、可复用的组件
  • 这样让我们的代码更加方便组织和管理,并且扩展性也更强

创建组件

类似于页面,自定义组件由 json wxml wxss js 4个文件组成

  • components, 里面存放我们之后自定义的公共组件
  • 常见一个自定义组件 my-cpn: 包含对应的四个文件

image-20231007180339644

自定义组件的步骤:

  1. 首先需要在 json 文件中进行自定义组件声明(将component 字段设为 true 可这一组文件设为自定义组件)
  2. 在 wxml 中编写属于我们组件自己的模板
  3. 在 wxss 中编写属于我们组件自己的相关样式
  4. 在 js 文件中, 可以定义数据或组件内部的相关逻辑

自定义组件细节

  • 自定义组件也是可以引用自定义组件的,引用方法类似于页面引用自定义组件的方式(使用usingComponents 字段)
  • 自定义组件和页面所在项目根目录名 不能以 "wx-" 为前缀,否则会报错
  • 如果在 app.json 的 usingComponents 声明某个组件,那么所有页面和组件可以直接使用该组件

image-20231007181102056

组件的样式细节

课题一:组件内的样式对外部样式的影响

  • 结论一:组件内的 class 样式,只对组件 wxml 内的节点生效, 对于引用组件的 Page 页面不生效
  • 结论二:组件内不能使用id选择器、属性选择器、标签选择器

课题二:外部样式对组件内样式的影响

  • 结论一:外部使用 class 的样式,只对外部 wxml 的 class 生效,对组件内是不生效的
  • 结论二:外部使用了 id 选择器、属性选择器不会对组件内产生影响
  • 结论三:外部使用了标签选择器,会对组件内产生影响

课题三:如何让 class 可以相互影响

  • 在 Component 对象中,可以传入一个 options 属性,其中 options 属性中有一个 styleIsolation(隔离)属性
  • styleIsolation 有三个取值:
    • isolated:表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(默认取值)
    • apply-shared:表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面
    • shared:表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了
js
Component({
  options: {
    styleIsolation: "apply-shared"
  }
})

组件的通信

https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/events.html

很多情况下,组件内展示的内容(数据、样式、标签),并不是在组件内写死的,而且可以由使用者来决定

image-20231007181153386

传递数据

给组件传递数据:

  • 大部分情况下,组件只负责布局和样式,内容是由使用组件的对象决定的
  • 所以,我们经常需要从外部传递数据给我们的组件,让我们的组件来进行展示

如何传递呢?

  • 使用 properties 属性

支持的类型:

  • String、Number、Boolean
  • Object、Array、null(不限制类型)

默认值:

  • 可以通过value设置默认值;

image-20231008164524802

传递样式

给组件传递样式:

  • 有时候,我们不希望将样式在组件内固定不变,而是外部可以决定样式

这个时候,我们可以使用 externalClasses 属性:

  1. 在 Component 对象中,定义 externalClasses 属性
  2. 在组件内的 wxml 中使用 externalClasses 属性中的 class
  3. 在页面中传入对应的 class,并且给这个 class 设置样式

image-20231008164916931

传递事件

有时候是自定义组件内部发生了事件,需要告知使用者,这个时候可以使用自定义事件

image-20231008165536798

页面直接调用组件方法

可在父组件里调用 this.selectComponent,获取子组件的实例对象

image-20231009090032598

插槽

https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html

slot 翻译为插槽:

  • 在生活中很多地方都有插槽,电脑的 USB 插槽,插板当中的电源插槽
  • 插槽的目的是让我们原来的设备具备更多的扩展性
  • 比如电脑的 USB 我们可以插入U盘、硬盘、手机、音响、键盘、鼠标等等

组件的插槽:

  • 组件的插槽也是为了让我们封装的组件更加具有扩展性
  • 让使用者可以决定组件内部的一些内容到底展示什么

单个插槽

除了内容和样式可能由外界决定之外,也可能外界想决定显示的方式

  • 比如我们有一个组件定义了头部和尾部,但是中间的内容可能是一段文字,也可能是一张图片,或者是一个进度条
  • 在不确定外界想插入什么其他组件的前提下,我们可以在组件内预留插槽

小程序中插槽是不支持默认值的

html
<view class="content">
  <!-- 如下是不生效的 -->
  <slot>哈哈哈</slot>
</view>
<view class="default">哈哈哈</view>

<style>
.default {
  display: none;
}
.content:empty + .default {
  display: block;
}
</style>

多个插槽

有时候为了让组件更加灵活, 我们需要定义多个插槽

image-20231009092957372

代码复用

behaviors

https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/lifetimes.html

behaviors 是用于组件间代码共享的特性,类似于一些编程语言中的 "mixins"

  • 每个 behavior 可以包含一组属性、数据、生命周期函数和方法
  • 组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用
  • 每个组件可以引用多个 behavior ,behavior 也可以引用其它 behavior

image-20231009104023749

组件生命周期

https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/lifetimes.html

组件的生命周期,指的是组件自身的一些函数,这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发

  • 其中,最重要的生命周期是 created attached detached ,包含一个组件实例生命流程的最主要时间点

自小程序基础库版本 2.2.3 起,组件的的生命周期也可以在 lifetimes 字段内进行声明(这是推荐的方式,其优先级最高)

image-20231009104921519

js
Component({
  lifetimes: {
    created() {
      console.log('组件被创建created')
    },
    attached() {
      console.log('组件被添加到组件数中atttached')
    },
    detached() {
      console.log('组件被移除组件树中derached')
    }
  }
})

组件所在页面的生命周期

还有一些特殊的生命周期,它们并非与组件有很强的关联,但有时组件需要获知,以便组件内部处理

  • 这样的生命周期称为 "组件所在页面的生命周期",在 pageLifetimes 定义段中定义

其中可用的生命周期包括:

image-20231009105313508

Component构造器

image-20231009105426548

image-20231009105445974

常备不懈,才能有备无患