您当前的位置: 首页 > 解决方案

深入wepy源码:wepy运行原理分析

  • 作者: admin
  • 发布于 2018-05-22 13:48:57
  • 来源:  
  • 栏目:解决方案

导语: 分析源码之前,我们先来回顾一下,wepy 的使用: <!-- 小程序入口 app.wpy --> <script> import wepy from 'wepy'; expo

 

分析源码之前,我们先来回顾一下,wepy 的使用:

<!-- 小程序入口 app.wpy --> <script> import wepy from 'wepy'; export default class extends wepy.app {   ...... } </script>

让我们一起看看 export 出来的 class,是怎么转换成小程序语言的。

《深入wepy源码:wpy文件编译过程》中,我们介绍了 wepy-cli 是如何编译 wpy 文件的,里面有说到,complie-script.js 在处理 script 代码时,会加入 wepy 初始化的代码。编译之后 dist 目录下的文件,如下:

// dist/app.js App(require('./npm/wepy/lib/wepy.js').default.$createApp(_default, {}));  // dist/pages/index.js  Page(require('./../npm/wepy/lib/wepy.js').default.$createPage(Index , 'pages/index'));

可以看出,主要调用了 $createApp 和 $createPage 方法。在看这两个方法之前,我们先来看一下 wepy 的目录结构,以便后面的分析更好理解。

wepy目录结构

├─wepy                    ├─src                          ├─app.js                全局app逻辑,请求优化、promisify API、拦截器功能等         ├─base.js               定义了 $createApp$createPage 等方法     ├─component.js          组件逻辑,脏值检查、组件通信等     ├─event.js              事件方法     ├─mixin.js              混合方法     ├─native.js             空,代码里用于app.js中重新定义wx接口     ├─page.js               继承component,page的一些优化     ├─util.js               工具方法     ├─wepy.js               入口文件   ├─test                   ├─...

createAppcreatePage

$createApp

// dist/app.js App(require('./npm/wepy/lib/wepy.js').default.$createApp(_default, {}));

$createApp() 返回了一个类型为 object 的 config,里面包含了 ['onLaunch', 'onShow', 'onHide', 'onError'] 这些方法。

还执行了 $initAPI(),主要利用 Object.defineProperty 的 get 方法,将返回封装为 promise,这里也是 API 实现 promise 写法的核心。

$createPage

// dist/pages/index.js  Page(require('./../npm/wepy/lib/wepy.js').default.$createPage(Index , 'pages/index'));

$createPage() 和 $createApp() 类似,只不过是返回的是 Page 的方法,此外,还在生命周期中,添加了数据脏值检查 $apply()

数据绑定

wepy 使用脏数据检查对原生小程序 setData 进行封装,在函数运行周期结束时执行脏数据检查。如果在异步函数中更新数据时,则需要手动执行 $apply()。贴一张官方的流程图。

10.jpg

在 $createPage() 中,会在生命周期中调用 $apply(),来看一下它的定义:

$apply (fn) {   if (typeof(fn) === 'function') {     fn.call(this);     this.$apply();   } else {     if (this.$$phase) {       this.$$phase = '$apply';     } else {       this.$digest();     }   } }

$$phase 标识是否有 脏数据检查 在运行,如果没有,则执行 $digest()

$digest() {   let k;   let originData = this.$data;   this.$$phase = '$digest';   this.$$dc = 0;   while (this.$$phase) {     this.$$dc++;     if (this.$$dc >= 3) {         throw new Error('Can not call $apply in $apply process');     }     ......     this.$$phase = (this.$$phase === '$apply') ? '$digest' : false;   } }

$digest() 执行时,主要是遍历 originData,将 originData[k] 和 this[k] 做对比,如果不一样,放到 readyToSet中,在循环之后,统一执行 setData 方法。

最后,在检查 $$phase 是否有被设置为 '$apply',如果是,则再做一次脏数据检查。



温馨提示:这篇文章没有解决您的问题?欢迎添加微信:18948083295,有微信小程序专业人员,保证有问必答。转载本站文章请注明转自http://www.okeydown.com/(微信小程序网)。

  • 微信扫描二维码关注官方微信
  • ▲长按图片识别二维码
关注我们

微信小程序官方微信

栏目最新
栏目推荐
返回顶部