开发
API

自定义组件扩展 definitionFilter

为了更好定制自定义组件的功能,可以使用自定义组件扩展机制。从小程序基础库版本 2.7.0 开始支持。

扩展后的效果

为了更好的理解扩展后的效果,先举一个例子:

behavior.js 中:

module.exports = Behavior({
  definitionFilter(defFields) {
    defFields.data.from = "behavior";
  },
});

component.js 中:

Component({
  data: {
    from: "component",
  },
  behaviors: [require("behavior.js")],
  ready() {
    // 此处会发现输出 behavior 而不是 component
    console.log(this.data.from);
  },
});

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

definitionFilter 方法在组件实例化(created 生命周期) 之前就会被调用。

使用扩展

Behavior() 构造器提供了新的定义段 definitionFilter ,用于支持自定义组件扩展。 definitionFilter 是一个函数,在被调用时会注入两个参数,第一个参数是使用该 behaviorcomponent/behavior 的定义对象,第二个参数是该 behavior 所使用的 behaviordefinitionFilter 函数列表。

需要注意的是,第一个参数是开发者传入Component/Behavior 的对象而非组件实例,结合下面的例子理解。

// component.js
const $init = {
  data: {},
  methods: {},
  behaviors: [require("behavior.js")],
};
Componet($init);
// behavior
module.exports = Behavior({
  definitionFilter(defFields, definitionFilterArr) {
    // 在上面的组件实例化时会将 $init 传给 defFields 参数
  },
});

举个稍复杂的例子来说明 definitionFilter 的调用时机以及传参逻辑:

在开发者工具中预览效果

// behavior3.js
module.exports = Behavior({
  definitionFilter(defFields, definitionFilterArr) {
    console.log("behavior3");
  },
});

// behavior2.js
module.exports = Behavior({
  behaviors: [require("behavior3.js")],
  definitionFilter(defFields, definitionFilterArr) {
    // definitionFilterArr[0](defFields)
    console.log("behavior2");
  },
});

// behavior1.js
module.exports = Behavior({
  behaviors: [require("behavior2.js")],
  definitionFilter(defFields, definitionFilterArr) {
    console.log("behavior1");
  },
});

// component.js
Component({
  behaviors: [require("behavior1.js")],
});

上述示例代码的打印顺序为:behavior3,behavior2,behavior1。具体的执行顺序和 definitionFilter 调用时传参逻辑如下图所示:

简单概括,definitionFilter 函数可以理解为当 A 使用了 B、B 使用了 C 时,A 声明就会调用 B 的 definitionFilter 函数并在第一个参数传入 A 的定义对象让 B 去过滤,同时在第二个参数传入 C 的 definitionFilter方法。

Bug & Tip

  • Tip: defFields 传入的用户定义对象是被深拷贝的,用户设置的不可枚举属性会被去除。从基础库 2.41.0 开始,传入 defFields 的对象不再深拷贝。
点击纠错
该文档是否对你的开发有所帮助?
有帮助
没帮助
该文档是否对你的开发有所帮助?
有帮助
没帮助