# 组件间关系

# 定义和使用组件间关系

有时需要实现这样的组件:

<custom-ul>
  <custom-li>item 1</custom-li>
  <custom-li>item 2</custom-li>
</custom-ul>

1
2
3
4
5

这个例子中, custom-ulcustom-li 都是自定义组件,它们有相互间的关系,相互间的通信往往比较复杂。此时在组件定义时加入 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生命周期之后
      }
    }
  },
  methods: {
    _getAllLi() {
      // 使用getRelationNodes可以获得nodes数组,包含所有已关联的custom-li,且是有序的
      const nodes = this.getRelationNodes('path/to/custom-li')
    }
  },
  ready() {
    this._getAllLi()
  }
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 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生命周期之后
      }
    }
  }
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

注意:必须在两个组件定义中都加入relations定义,否则不会生效。

# 关联一类组件

有时,需要关联的是一类组件,如:

<custom-form>
  <view>
    input
    <custom-input></custom-input>
  </view>
  <custom-submit>submit</custom-submit>
</custom-form>

1
2
3
4
5
6
7
8

custom-form 组件想要关联 custom-inputcustom-submit 两个组件。此时,如果这两个组件都有同一个behavior:

// path/to/custom-form-controls.js
module.exports = Behavior({
  // ...
})

1
2
3
4
5
// path/to/custom-input.js
const customFormControls = require('./custom-form-controls')
Component({
  behaviors: [customFormControls],
  relations: {
    './custom-form': {
      type: 'ancestor', // 关联的目标节点应为祖先节点
    }
  }
})

1
2
3
4
5
6
7
8
9
10
11
// path/to/custom-submit.js
const customFormControls = require('./custom-form-controls')
Component({
  behaviors: [customFormControls],
  relations: {
    './custom-form': {
      type: 'ancestor', // 关联的目标节点应为祖先节点
    }
  }
})

1
2
3
4
5
6
7
8
9
10
11

则在 relations 关系定义中,可使用这个behavior来代替组件路径作为关联的目标节点:

// path/to/custom-form.js
const customFormControls = require('./custom-form-controls')
Component({
  relations: {
    customFormControls: {
      type: 'descendant', // 关联的目标节点应为子孙节点
      target: customFormControls
    }
  }
})

1
2
3
4
5
6
7
8
9
10
11

# relations 定义段

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

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