- 微信视频号发不了视频?
微信视频号发不了视频 签名头像都改不了!也用不了
2021-04-12 - 为小程序添加生命周期(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 展示了小程序给我们提供的生命周期触发顺序。但缺少一些生命周期。或许是小程序认为那些不重要,我们用不到吧。让我们来补充一下,这对调试、开发插件等情形很有帮助 增加 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 一起封装起来。 增加 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 合并 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 总结: 利用 behavior 中的 definitionFilter,可在组件实例创建前修改原配置。模拟 beforeCreate 生命周期。 利用 properties 传 boolean 值,通过 observers 监控传值字段 达到获取组件挂载时第一时间的 this 实例数据,模拟 attach 生命周期。 已知不足是:需要在要调用 attach 生命周期的组件上加入 attach(可自定义)字段, 有可能导致数据字段冲突,但此周期多用于调试,仅当需要调试组件,查看挂载时数据时,手动添加也没什么问题。 水平有限,如有错误之处,请留言指教。 代码片段
2022-06-03