微信小程序-自定义组件扩展

数据监听器

数据监听器主要用于监听任何属性(properties)和数据(data)的变化

在组件中需要进行数据监听,需要用到observers

如果是data中的数据,数据变化时可触发监听

如果是properties的数据,数据传递时就会触发监听


组件通讯

父往子传递

properties就是父子传递的方式

子往父传递

当子组件需要向父组件发送数据时,它会触发一个自定义事件,并把数据作为事件的一部分传递出去。父组件则监听这个事件,并在事件触发时执行相应的方法来接收数据。

子组件通过触发函数调用 this.triggerEvent(eventName, detail, options) 方法来定义并触发一个自定义事件eventName,并添加想要传输的数据detail。

1
2
3
4
<!-- 引用子组件,并监听其自定义事件 -->
<my-child
bind:eventName="handleChildEvent"
></my-child>

在引用子组件时,将自定义事件作为属性,绑定触发一个处理函数

处理方法会接收到一个事件对象 event。子组件传递的数据会存储在 event.detail 属性中


获取子组件实例

在父组件中,我们可以通过类选择器或者id选择器作为参数,调用this.selectComponent方法来获取到子组件的实例,就可以获取到子组件的所有信息


组件的生命周期

组件的生命周期需要在lifetimes字段进行声明,组件的生命周期有五个函数

  • options (组件选项,仅限组件)created:指主键实例被创建好时执行
  • attached:指主键被挂载到页面上时执行
  • ready
  • moved
  • detached:组件被销毁时执行

注:在created声明周期时,不能调用setData函数


组件所在页面的生命周期

组件所在也页面的生命周期有四个,需要在pageLifetimes进行声明

  • show:监听组件所在的页面展示状态
  • hide:监听组件所在的页面隐藏状态
  • resize
  • routeDone

使用组件来构造页面

小程序中区分了组件和页面,但仍然可以使用component来构造页面

注意事项:

  1. 要求.json文件中必须包含usingComponents字段
  2. 里面的配置项要与Component保持一致
  3. 页面中Page方法有一些钩子函数,和事件监听方法等必须放在method中

最佳实践中,不推荐直接将组件来作为页面使用,而是选择页面容器模式,页面的主要职责是装组件,作为一个容器,不实现具体逻辑


组件复用机制

Behavior 是微信小程序中实现代码复用和逻辑共享的强大工具。通过将通用的数据、方法和生命周期封装到 Behavior 中,你可以大大减少代码冗余,提高开发效率,并使代码结构更加清晰和易于维护。在实际项目中,它被广泛应用于处理各种跨组件/页面的通用逻辑。

我们可以在behavior中预定义一些逻辑,例如上拉加载更多数据,在其中预定义了一些方法和数据

当组合在页面或组件中时,相同的数据会覆盖掉behavior中的数据,然后可以调用预定义的方法,来执行相应的逻辑


微信小程序 Behavior 冲突解决原则

核心思想是:页面/组件拥有最终的控制权。 大多数情况下,如果页面/组件与 Behavior 定义了同名的字段,页面/组件的定义会覆盖 Behavior 的定义。但生命周期函数是例外,它们会按顺序执行。

1. data 对象 (数据字段)

  • 合并方式: 浅合并 (Shallow Merge) + 覆盖。

  • 冲突解决:

    • 如果 Behavior 和页面/组件都定义了某个同名的数据字段(例如 message),页面/组件中的值会覆盖 Behavior 中的值
    • 如果数据字段是对象,且同名,则整个对象会被替换,而不是深度合并。
    • 如果只有 Behavior 定义了,则该字段会被合并到页面/组件的 data 中。
    • 如果只有页面/组件定义了,则该字段保持不变。

2. properties 对象 (组件属性,仅限组件)

  • 合并方式: 浅合并 (Shallow Merge) + 覆盖。
  • 冲突解决:data 类似,如果 Behavior 和组件都定义了某个同名属性,组件中的定义会覆盖 Behavior 中的定义

3. methods 对象 (方法)

  • 合并方式: 覆盖。

  • 冲突解决: 如果 Behavior 和页面/组件都定义了某个同名方法,页面/组件中的方法会覆盖 Behavior 中的方法。这允许你在特定页面/组件中对 Behavior 提供的通用方法进行定制或重写。

4. 生命周期函数 (lifetimes, pageLifetimes)

  • 合并方式: 顺序执行 (而非覆盖)。

  • 冲突解决:

    • Behavior 中定义的生命周期函数会先于页面/组件中定义的同名生命周期函数执行。
    • 如果引入了多个 Behavior,它们的生命周期函数会按照在 behaviors 数组中声明的顺序依次执行,然后再执行页面/组件自身的生命周期函数。
    • 注意: createdattached 是特例,它们在 Behavior 中执行时,this.data 尚未完全合并,可能无法访问到页面/组件独有的数据。通常建议在 ready 中进行数据初始化。

5. behaviors 数组 (引入其他 Behavior)

  • 合并方式: 数组连接 (Concatenation)。

  • 冲突解决: 数组会进行合并。如果一个组件引入了多个 Behavior,并且这些 Behavior 之间也有重叠(例如都定义了 data.a),那么后引入的 Behavior 会覆盖先引入的 Behavior。最终,页面/组件的定义会覆盖所有 Behavior 的定义。

  1. observers (数据监听器,仅限组件)
  • 合并方式: 数组连接。
  • 冲突解决: Behavior 和组件的 observers 数组会合并。所有定义的监听器都会被执行。
  1. relations (组件间关系,仅限组件)
  • 合并方式: 对象合并。
  • 冲突解决: 如果 Behavior 和组件定义了同名的 relations 键,组件的定义会覆盖 Behavior 的定义
  1. externalClasses (外部样式类,仅限组件)
  • 合并方式: 数组连接。
  • 冲突解决: Behavior 和组件的 externalClasses 数组会合并。
  1. options (组件选项,仅限组件)
  • 合并方式: 对象合并。
  • 冲突解决: 如果 Behavior 和组件定义了同名的 options 键,组件的定义会覆盖 Behavior 的定义

外部样式类

外部样式类本质上是组件内部预留的占位符类名。当组件被引用时,外部可以通过一个特定的属性将实际的样式类名传递给这些占位符,从而实现对组件内部元素的样式控制。

可以把它想象成一个插槽,但这个插槽是用来插入CSS类名的。

在子组件中定义好默认的样式,但配置额外的样式占位符,并通过externalClasses: [‘custom-class’, ‘text-class’]关键字声明

在调用组件时,在wxml的模板文件中将外部样式类作为属性传递值,或者直接在父组件的css文件中编辑样式文件即可

CSS 变量(Custom Properties)

小程序也支持 CSS 变量(--var-name: value;)。在某些场景下,CSS 变量可以作为外部样式类的替代方案,甚至更优:

  • 外部样式类: 适用于需要完全替换或添加一组样式规则的场景(如改变背景色、边框、字体等)。它传递的是一个完整的类名。
  • CSS 变量: 适用于需要调整组件内部某个具体样式属性值的场景(如主题色、间距、字体大小等)。它传递的是一个值。

示例(CSS 变量):
组件内部:

1
2
3
4
5
/* components/my-button/my-button.wxss */
.button-wrapper {
background-color: var(--button-bg-color, #007bff); /* 默认蓝色 */
padding: var(--button-padding, 10px 20px);
}

外部使用:

1
2
3
4
5
/* pages/index/index.wxss */
my-button {
--button-bg-color: red;
--button-padding: 5px 10px;
}

CSS 变量的优势在于它更细粒度,不需要暴露内部的 DOM 结构,更符合“配置”而非“覆盖”的理念。但它不能像外部样式类那样直接添加新的 CSS 规则(比如 border),只能修改已有的属性值。



微信小程序-自定义组件扩展
http://blog.170827.xyz/2025/07/07/微信小程序-自定义组件扩展/
作者
XIAOBAI
发布于
2025年7月7日
许可协议