自定义组件扩展
收藏我的收藏
为了更好地定制自定义组件的功能,可以使用自定义组件扩展机制。从小程序基础库版本 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
定义段里的内容。系统会在组件实例化(created 生命周期)之前调用 definitionFilter 方法。
使用扩展
Behavior()
构造器提供了新的定义段 definitionFilter
,用于支持自定义组件扩展。 definitionFilter
是一个函数,在被调用时会注入两个参数,第一个参数是使用该 behavior
的 component/behavior
的定义对象,第二个参数是该 behavior
所使用的 behavior
的 definitionFilter
函数列表。需要注意的是,第一个参数是开发者传入
Component/Behavior
的对象而非组件实例,结合下面的例子理解。// component.js const $init = { data: {}, methods: {}, behaviors: [require("behavior.js")], }; Component($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
调用时传参逻辑如下图所示:简单概括,当 A 使用 B 且 B 使用 C 时,A 的声明会触发调用 B 的 definitionFilter 函数,该函数第一个参数接收 A 的定义对象供 B 过滤,同时在第二个参数传入 C 的
definitionFilter
方法。Bug & Tip
Tip: 系统会深拷贝
defFields
传入的用户定义对象,并去除用户设置的不可枚举属性。从基础库 2.41.0
开始,系统不再深拷贝传入 defFields
的对象。