从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现 (3)

pageframe.html页面在dom ready之后触发注入并执行具体页面相关的代码,此时通过history.pushState方法修改webview的src但是webview并不会发送页面请求。

从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现

pageframe.html模板生成的内容除小程序基础库视图层的底层功能之外,还包括小程序所有页面的模板信息、配置信息以及样式内容,这些都可以在生成pageframe.html的dom结构中窥探一二。

从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现

那么,既然每个视图层页面由pageframe模板生成,那么小程序每个页面独有的页面内容如dom和样式等如何生成呢,这主要是利用nw.js的executeScript方法来执行一段js脚本来注入只与当前页面相关的代码,包括当前页面的配置,注入当前页的css以及当前页面的virtual dom的生成,注入的代码如下:

从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现

最终生成的js代码(拿pages/index/index为例)如下图:

从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现

其中:

history.pushState('','', 'http://127.0.0.1:59524/__pageframe__/pages/index/index')

这句代码的作用修改当前webview的src,因为视图层的webview的src为pageframe.html,通过这句代码将其变更为具体的页面地址。

另外,需要注意的是nw.js的executeScript方法注入的代码是需要时机的,需要等到视图层的初始化工作准备ready之后才行,那么这个时机如何知道呢?细心的读者可能发现,在pageframe模板的最后一个script的内容:

<script>alert("DOCUMENT_READY")</script>

这个从字面意思可以看出此时应该是页面dom ready的一个时机,通过alert来进行通知。
alert能通知消息?当然可以的,在nw.js的webview中alert、prompt对应的弹框是被会阻止的,那么通过为webview绑定dialog事件来知道是那种弹框类型,以及提示内容,具体可以查看这篇文章。例如小程序开发者工具绑定事件部分代码(便于查看有修改):

this.webview.on('dialog', (a) => { a.preventDefault(); const b = a.messageType || '', c = a.messageText, d = a.dialog; if ('alert' === b) { c === 'DOCUMENT_READY' && (this.documentReady = !0, this.loadPage()) } ... })

这样方法loadPage就会触发nw注入并执行页面相关的代码。最终生成的页面视图对应dom结构如下图:

从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现

可以看出,视图页面生成的dom结构中,document.body已无pageframe.html模板中对应body中的script内容,这是因为视图层的WAWebview.js在通过virtual dom生成真实dom过程中,它会挂载到页面的document.body上,覆盖掉pageframe.html模板中对应document.body的内容。

业务逻辑层页面的实现

小程序将所有业务代码置于同一个线程中运行,小程序开发者工具是在一个webview中执行;webview中的appservice.html引入业务代码js之外,还有后台服务内嵌的一些基础功能代码,appservice.html对应的模板内容如下:

从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现


经过后台服务的处理,模板中的各种占位符就被对应的js内容注入,下面就来简单说几个重要的注入内容:

<!-- wxconfig -->: 小程序的配置项,包括用户自定义与系统默认的整合结果。在控制台输入__wxConfig可以看出打印结果

从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现

<!--devtoolsconfig-->:小程序开发者配置,包括开发者工具版本,设置的请求域名、默认开发者工具的设置以及访问Native方法需要permission的方法。控制台输入__devtoolsconfig可以看到其对应的信息

从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现

<!-- wxmlxcjs -->: 调用wcc可执行命令生成的小程序注册所有页面wxml对应的js脚本内容,js脚本提供$gwx方法。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyfzzp.html