小程序开发框架 —— 框架接口汇总(四)

relations

组件间关系,定义和使用组件间关系。

// path/to/custom-ul.js
Component({
  relations: {
    './custom-li': {
      type: 'child', // 关联的目标节点应为子节点
      linked(target) {
        // 每次有 custom-li 被插入时执行,target 是该节点实例对象,触发在该节点 attached 生命周期之后
      },
      linkChanged(target) {
        // 每次有 custom-li 被移动后执行,target 是该节点实例对象,触发在该节点 moved 生命周期之后
      },
      unlinked(target) {
        // 每次有 custom-li 被移除时执行,target 是该节点实例对象,触发在该节点 detached 生命周期之后
      },
    },
  },
});
// path/to/custom-li.js
Component({
  relations: {
    './custom-ul': {
      type: 'parent', // 关联的目标节点应为父节点
      linked(target) {
        // 每次被插入到 custom-ul 时执行,target 是 custom-ul 节点实例对象,触发在attached生命周期之后
      },
      linkChanged(target) {
        // 每次被移动后执行,target 是 custom-ul 节点实例对象,触发在moved生命周期之后
      },
      unlinked(target) {
        // 每次被移除时执行,target 是 custom-ul 节点实例对象,触发在detached生命周期之后
      },
    },
  },
});
// 注意:必须在两个组件定义中都加入relations定义,否则不会生效。

relations 定义段

relations 定义段包含目标组件路径及其对应选项,可包含的选项见下表。

选项类型是否必填描述
typeString目标组件的相对关系,可选的值为 parent 、 child 、 ancestor 、 descendant
linkedFunction关系生命周期函数,当关系被建立在页面节点树中时触发,触发时机在组件 attached 生命周期之后
linkChangedFunction关系生命周期函数,当关系在页面节点树中发生改变时触发,触发时机在组件 moved 生命周期之后
unlinkedFunction关系生命周期函数,当关系脱离页面节点树时触发,触发时机在组件 detached 生命周期之后
targetString如果这一项被设置,则它表示关联的目标节点所应具有的 behavior,所有拥有这一 behavior 的组件节点都会被关联

behaviors

用于自定义组件间代码共享的特性,类似于一些编程语言中的 mixins 或 traits。每个 behavior 可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用。 每个组件可以引用多个 behavior behavior 也可以引用其它 behavior 。

详细的 Behavior 介绍请参考 Behavior.

在组件中使用

组件引用时,在 behaviors 定义段中将它们逐个列出即可。

// my-behavior.js
export default Behavior({
  behaviors: [
    /* 可引用其他 behavior */
  ],
  properties: { myBehaviorProperty: { type: String } },
  data: { myBehaviorData: {} },
  lifetimes: { attached() {} },
  methods: { myBehaviorMethod() {} },
});
import myBehavior  from '/my-behavior';
 
Component({
  behaviors: [myBehavior],
});

👉 立即免费领取开发资源,体验涂鸦 MiniApp 小程序开发。  

同名字段的覆盖和组合规则

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

  • 如果有同名的属性 (properties) 或方法 (methods):
  1. 若组件本身有这个属性或方法,则组件的属性或方法会覆盖 behavior 中的同名属性或方法;
  2. 若组件本身无这个属性或方法,则在组件的 behaviors 字段中定义靠后的 behavior 的属性或方法会覆盖靠前的同名属性或方法;
  3. 在 2 的基础上,若存在嵌套引用 behavior 的情况,则规则为:父 behavior 覆盖 子 behavior 中的同名属性或方法。
  • 如果有同名的数据字段 (data):

    • 若同名的数据字段都是对象类型,会进行对象合并;
    • 其余情况会进行数据覆盖,覆盖规则为:组件 > 父 behavior > 子 behavior 、 靠后的 behavior > 靠前的 behavior。(优先级高的覆盖优先级低的,最大的为优先级最高)
  • 生命周期函数不会相互覆盖,而是在对应触发时机被逐个调用:

    • 对于不同的生命周期函数之间,遵循组件生命周期函数的执行顺序;
    • 对于同种生命周期函数,遵循如下规则:
      • behavior 优先于组件执行;
      • 子 behavior 优先于 父 behavior 执行;
      • 靠前的 behavior 优先于 靠后的 behavior 执行;
    • 如果同一个 behavior 被一个组件多次引用,它定义的生命周期函数只会被执行一次。

definitionFilter

定义段过滤器,用于自定义组件扩展。

// behavior.js
export default Behavior({
  definitionFilter(defFields) {
    defFields.data.from = 'behavior';
  },
});
 
// component.js
import myBehavior from './behavior.js'
Component({
  data: {
    from: 'component',
  },
  behaviors: [myBehavior],
  ready() {
    console.log(this.data.from); // 此处会发现输出 behavior 而不是 component
  },
});

通过例子可以发现,自定义组件的扩展其实就是提供了修改自定义组件定义段的能力,上述例子就是修改了自定义组件中的 data 定义段里的内容。

高级进阶

组件间通信与事件

组件间的基本通信方式有以下几种。

  • TYML 数据绑定:用于父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容数据。
  • 事件:用于子组件向父组件传递数据,可以传递任意数据。
  • 如果以上两种方式不足以满足需要,父组件还可以通过 this.selectComponent 方法获取子组件实例对象,这样就可以直接访问组件的任意数据和方法。
监听事件

事件系统是组件间通信的主要方式之一。自定义组件可以触发任意的事件,引用组件的页面可以监听这些事件。关于事件的基本概念和用法,参见 事件

监听自定义组件事件的方法与监听基础组件事件的方法完全一致:

示例代码:

<!-- 当自定义组件触发 myevent 事件时,调用“onMyEvent”方法 -->
<component-tag-name bind:myevent="onMyEvent" />
Page({
  onMyEvent(event) {
    event.detail; // 自定义组件触发事件时提供的detail对象
  },
});

触发事件

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

示例代码:

<!-- 在自定义组件中 -->
<button bind:tap="onTap">点击这个按钮将触发“myevent”事件</button>
Component({
  properties: {},
  methods: {
    onTap() {
      var myEventDetail = {}; // detail对象,提供给事件监听函数
      this.triggerEvent('myevent', myEventDetail);
    },
  },
});

组件模板的 slot

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

一个组件的 tyml 中支持有一个 slot 或者多个 slot(需启用 multipleSlots: true

在组件的 tyml 中使用多个 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>

👉 立即免费领取开发资源,体验涂鸦 MiniApp 小程序开发。  

组件数据中的纯数据字段

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

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

指定“纯数据字段”的方法是在 Component 构造器的 options 定义段中指定 pureDataPattern 为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段。

示例代码:

Component({
  options: {
    pureDataPattern: /^_/, // 指定所有 _ 开头的数据字段为纯数据字段
  },
  data: {
    a: true, // 普通数据字段
    _b: true, // 纯数据字段
  },
  methods: {
    myMethod() {
      this.data._b; // 纯数据字段可以在 this.data 中获取
      this.setData({
        c: true, // 普通数据字段
        _d: true, // 纯数据字段
      });
    },
  },
});

上述组件中的纯数据字段不会被应用到 TYML 上:

<view ty:if="{{a}}"> 这行会被展示 </view>
<view ty:if="{{_b}}"> 这行不会被展示 </view>

组件属性中的纯数据字段

属性也可以被指定为纯数据字段(遵循 pureDataPattern 的正则表达式)。

属性中的纯数据字段可以像普通属性一样接收外部传入的属性值,但不能将它直接用于组件自身的 TYML 中。

示例代码:

Component({
  options: {
    pureDataPattern: /^_/,
  },
  properties: {
    a: Boolean,
    _b: {
      type: Boolean,
      observer() {
        // 不要这样做!这个 observer 永远不会被触发
      },
    },
  },
});

注意:属性中的纯数据字段的属性 observer 永远不会触发!如果想要监听属性值变化,使用 数据监听器 代替。

使用数据监听器监听纯数据字段

数据监听器可以用于监听纯数据字段(与普通数据字段一样)。这样,可以通过监听、响应纯数据字段的变化来改变界面。

下面的示例是一个将 JavaScript 时间戳转换为可读时间的自定义组件。

Component({
  options: {
    pureDataPattern: /^timestamp$/, // 将 timestamp 属性指定为纯数据字段
  },
  properties: {
    timestamp: Number,
  },
  observers: {
    timestamp() {
      // timestamp 被设置时,将它展示为可读时间字符串
      var timeString = new Date(this.data.timestamp).toLocaleString();
      this.setData({
        timeString: timeString,
      });
    },
  },
});
<view>{{timeString}}</view>

👉 立即免费领取开发资源,体验涂鸦 MiniApp 小程序开发。  

  • 37
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IoT砖家涂拉拉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值