评论

为小程序添加生命周期(beforeCreate和attach)

小程序生命周期拓展

示例 1

index 页面

//  index.json
{
  "usingComponents": {
    "parent":"/component/parent/parent"
  }
}
// index.wxml
 <parent />

// index.js  这里使用Component来取代Page构造器生成页面实例。

Component({
  lifetimes: {
    created() {
      console.log("index --> created");
    },
    attached() {
      console.log("index --> attached");
    },
  },
  methods: {
    onLoad() {
      console.log("index --> onLoad");
    },
  },
});

parent 组件

//parent.json
{
  "usingComponents": {
    "son": "/components/son/son"
  }
}

//parent.wxml
<son />

//parent.js
Component({
  lifetimes: {
    created() {
      console.log("parent --> created");
    },
      attached() {
      console.log("parent --> attached");
    },
  },
});


son 组件

//son.json
{
  "usingComponents": {}
}

//son.wxml
<test>son</test>

//son.js
Component({
  lifetimes: {
    created() {
      console.log("son --> created");
    },
    attached() {
      console.log("son --> attached");
    },
  },
});

编译后 控制台打印如下

son --> created
parent --> created
index --> created
index --> attached
parent --> attached
son --> attached
index–>onLoad

小结: 组件建立是由内而外的。页面所有组件都挂载到页面组件后,才由外向内触发每个子组件的 attached 周期。最后触发页面的(最外层组件)onLoad 周期。
值得注意的是每个组件 attached 周期触发时,this.data 数据 可能被上级组件传入多次,导致获取不到首次挂载时的 this.data 对象。对调试等一些情况是不友好。

beforeCreate 和 attach

示例 1 展示了小程序给我们提供的生命周期触发顺序。但缺少一些生命周期。或许是小程序认为那些不重要,我们用不到吧。让我们来补充一下,这对调试、开发插件等情形很有帮助

  1. 增加 attach 周期 (可用作复杂组件调试场景,相比与 attached 只是触发时机不一样,this.data.fields 是首次挂载数据时的实例数据.而 attached 触发时,由于上级组件传入数据导致实例data中的数据已不是当初的样子了,在应对复杂组件应用的调试时不是很好用)

分别在示例 1 增加 如下代码

<!-- index.wxml  增加 attach 传值-->
<parent attach />
<!-- parent.wxml  增加 attach 传值-->
<son attach />
// parent.js
Component({
  //新增
  properties: {
    attach: Boolean,
  },
  observers: {
    attach() {
      console.log("parent --> attach");
    },
  },
  //...省略之前示例1中的代码
});
// son.js
Component({
  //新增
  properties: {
    attach: Boolean,
  },
  observers: {
    attach() {
      console.log("son --> attach");
    },
  },
  //...省略之前示例1中的代码
});

控制台打印如下

son --> created
son --> attach
parent --> created
parent --> attach
index --> created
index --> attached
parent --> attached
son --> attached

至此我们有了 attach 生命周期 利用这个周期,我们可以看到组件挂载时 this 上的所有信息,在某写情形下对代码优化,调试带来方便。 稍后我们将它和 beforeCreate 一起封装起来。

  1. 增加 beforeCreate 周期 (触发时机在实例数据建立之前 this 指向当前配置)

因为 created 周期无法修改实例数据、attached 周期又触发太晚、配置阶段又不能调用函数 。 某些情形下(全局注入等)还是需要 beforeCreate 周期的。

办法是 可以为单个组件添加 或 劫持 Component 全局添加如下 behavior

const beforeCreate = Behavior({
  definitionFilter(opt) {
    opt.lifetimes?.beforeCreate?.call(opt);
    delete opt.lifetimes?.beforeCreate; //删除 避免冲突吧。
  },
});

// 全局注入beforeCreate
const originalComponent = Component;
Component = function (options) {
  options.behaviors ||= [].push(beforeCreate);
  return originalComponent(options);
};

编译后 控制台打印如下

parent --> beforeCreate
son --> beforeCreate
son --> created
parent --> created
index --> created
index --> attached
parent --> attached
son --> attached
index --> onLoad

  1. 合并 attach 和 beforeCreate
// beforeCreateAndAttach.js

export const beforeCreateAndAttach = Behavior({
  definitionFilter(opt) {
    //attach  注意这里没有对properties和observers字段中判断是否已经有了attach字段
    (opt.properties ||= {}).attach = Boolean;
    (opt.observers ||= {}).attach = function () {
      delete this.data.attach; // 没什么用了
      opt.lifetimes?.attach?.call(this);
    };
    // beforeCreate
    opt.lifetimes?.beforeCreate?.call(opt);
    delete opt.lifetimes?.beforeCreate; // 没什么用了
  },
});

//全局注入
const originalComponent = Component;
Component = function (options) {
  (options.behaviors ||= []).push(beforeCreateAndAttach);
  return originalComponent(options);
};
// app.js

import "./beforeCreateAndAttach";
App({});

index --> beforeCreate
parent --> beforeCreate
son --> beforeCreate
son --> created
son --> attach
parent --> created
parent --> attach
index --> created
index --> attached
parent --> attached
son --> attached
index --> onLoad

总结:

  1. 利用 behavior 中的 definitionFilter,可在组件实例创建前修改原配置。模拟 beforeCreate 生命周期。

  2. 利用 properties 传 boolean 值,通过 observers 监控传值字段 达到获取组件挂载时第一时间的 this 实例数据,模拟 attach 生命周期。
    已知不足是:需要在要调用 attach 生命周期的组件上加入 attach(可自定义)字段, 有可能导致数据字段冲突,但此周期多用于调试,仅当需要调试组件,查看挂载时数据时,手动添加也没什么问题。

  3. 水平有限,如有错误之处,请留言指教。

  4. 代码片段

最后一次编辑于  2022-06-03  
点赞 1
收藏
评论

1 个评论

  • 木勒得古力
    木勒得古力
    发表于移动端
    2022-06-05
    吓死爸爸
    2022-06-05
    赞同
    回复 1
    • 木勒得古力
      木勒得古力
      发表于移动端
      2022-06-05
      怎么登陆和平精英?
      2022-06-05
      回复
登录 后发表内容