浅析鸿蒙 JavaScript GUI 技术栈

论坛 期权论坛     
选择匿名的用户   2021-5-30 01:37   648   0
<div id="js_content">
<p style="text-align: center"><img src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-7cc15e151b6337e767663006a70cc6b6"><br></p>
<p style="text-align: left"><strong>作者:doodlewin</strong><strong>d  雪碧</strong><br></p>
<p style="text-align: left"><strong>https://zhuanlan.zhihu.com/p/240594356</strong></p>
<p>众所周知,刚刚开源的「鸿蒙 2.0」以 JavaScript 作为 IoT 应用开发的框架语言。这标志着继 SpaceX 上天之后,JavaScript 再一次蹭到了新闻联播级的热点。这么好的机会,只拿来阴阳怪气实在太可惜了。作为科普,这篇文章不会拿着放大镜找出代码中的槽点来吹毛求疵,而是希望通俗地讲清楚它所支持的 GUI 到底是怎么一回事。只要对计算机基础有个大概的了解,应该就不会对本文有阅读上的障碍。<br></p>
<p>我们已经知道在「鸿蒙 2.0」上,开发者只需编写形如 Vue 组件式的 JavaScript 业务逻辑,即可将其渲染为智能手表等嵌入式硬件上的 UI 界面。这个过程中需要涉及哪些核心的模块呢?这些模块中又有哪些属于自研,哪些使用了现成的开源项目呢?这里将其分为自上而下的三个抽象层来介绍:</p>
<ul><li><p>JS 框架层,可理解为一个大幅简化的 Vue 式 JavaScript 框架</p></li><li><p>JS 引擎与运行时层,可理解为一个大幅简化的 WebKit 式运行时</p></li><li><p>图形渲染层,可理解为一个大幅简化的 Skia 式图形绘制库</p></li></ul>
<p>这三个抽象层,整体构成了一套面向嵌入式硬件的 GUI 技术栈。不同于许多高呼「不明觉厉 / 深不可测」的舆论,个人认为至少对于 GUI 部分,国内凡是接触过目前主流 Hybrid 式跨端方案或 JS 运行时研发的一线开发者,都很容易从源码出发来理解它。下面逐层对其做一些解读和分析。</p>
<h2>JS 框架层</h2>
<p>从最顶层的视角出发,要想用「鸿蒙 2.0」渲染出一段动态的文本,你只需要编写如下的 HML(类 XML)格式代码:</p>
<pre class="blockcode"><code class="language-go">&lt;!-- hello.hml --&gt;
&lt;text onclick&#61;&#34;boil&#34;&gt;{<!-- -->{hello}}&lt;/text&gt;</code></pre>
<p>然后在同级目录编写这样的 JavaScript:</p>
<pre class="blockcode"><code class="language-go">// hello.js
export default {
  data: {
    hello: &#39;PPT&#39;
  },
  boil() {
    this.hello &#61; &#39;核武器&#39;;
  }
}
</code></pre>
<p>这样只要点击文本,就会调用 <code>boil</code> 方法,让 <code>PPT</code> 变成 <code>核武器</code>。</p>
<p>这背后发生了什么呢?熟悉 Vue 2.0 的同学应该会立刻联想到下面这几件事:</p>
<ul><li><p>需要对 XML 的预处理机制,将其转换为 JS 中的嵌套函数结构。这样只需在运行时做一次简单 eval ,即可用 JS 生成符合 XML 结构的 UI。</p></li><li><p>需要事件机制,使得触发 <code>onclick</code> 事件时能执行相应回调。</p></li><li><p>需要数据劫持机制,使得对 <code>this.hello</code> 赋值时能执行相应回调。</p></li><li><p>需要能在回调中更新 UI 对象控件。</p></li></ul>
<p>这几件事分别是怎么实现的呢?简单说来是这样的:</p>
<ul><li><p>XML 预处理依赖现成的 NPM 开源包,从而把 XML 中的 <code>onclick</code> 属性转换为 JS 对象的属性字段。</p></li><li><p>事件的注册和触发都直接由 C&#43;&#43; 实现。如上一步所获得的 JS 对象 <code>onclick</code> 属性会在 C&#43;&#43; 中被检查和注册,相当于全部组件均为原生。</p></li><li><p>数据劫持机制用 JS 实现,是个基于 <code>Object.defineProperty</code> 的(几百行量级的)ViewModel。</p></li><li><p>UI 控件的更新,会在 ViewModel 自动执行的 JS 回调中,调用 C&#43;&#43; 的原生方法实现。这部分完全隐式完成,并未开放 <code>document.createElement</code> 式的标准化 API。</p></li></ul>
<p>由于大量常见 JS 框架中的能力都直接做进了 C&#43;&#43;,所以整套 GUI 技术栈里用纯 JavaScript 所实现的东西(主要见 <code>ace_lite_jsfwk</code> 仓库下的 <code>core/index.js</code>、<code>observer.js</code> 和 <code>subject.js</code>),相当于有且只有这么一个功能:</p>
<p>一个可以 watch 的 ViewModel。</p>
<p>至于纯 JS 框架部分的实现复杂度和质量,客观地说如果是个人业余作品,可以当作校招面试中不错的加分项。</p>
<h2>JS 引擎与运行时层</h2>
<p>理解了 JS 框架层之后,我们既可以认为「鸿蒙 2.0」选择把高度简化后的 Vue 深度定制进了 C&#43;&#43; 里,也可以认为它紧密围绕着高度简化(且私有)的 DOM 实现了配套的前端框架。因此要想继续探索这套 GUI 的原理,我们就必须进入其 C&#43;&#43; 部分,了解其 JS 引擎与运行时层的实现。</p>
<p>JS 引擎和运行时之间&
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP