微信小程序底层的实现原理是怎样的? 财富值42

2016-11-06 18:44发布

微信小程序底层的实现原理是怎样的?
9条回答
曾经最美1 - 这个人很懒,什么都没留下
1楼 · 2016-11-06 18:55.采纳回答
几天了,没心情细分代码
我猜测是,js->bridge->系统,然后,系统->bridge->js

webviewbridge这个东西,前端方面我稍微写过一点,以这个为基础猜的。

微信应用号充当了bridge的功能

如果是这样,性能可以和客户端媲美,但是组件的定制性差,因为组件是调取系统的不好改。

也可能调用的不是系统组件而是微信写在微信app内的组件,这样的话定制问题就可以等微信慢慢开放接口了。

待我睡醒细看。
作者:赵九州
链接:如何评价 9 月 21 日开始内测的「微信小程序」? - 赵九州的回答
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

笔者注:本文来自于迅雷首席工程师刘智聪的个人分享,他毕业于南昌大学化学系,加入迅雷后设计开发了多款迅雷核心产品,凭借“大规模网络流媒体服务关键支撑技术”项目获得2015年国家科学技术进步奖二等奖,同时也是第四代UI交互技术-----BOLT 界面引擎的发明人,目前担任WebApp解决方案商--火速移动的首席技术顾问。


21号晚上正和朋友一起打牌,难得的小七对刚刚定口,突然间手机传来了“叮咚”的消消息提示音,随后就是“叮叮,咚咚”的连续震动。打开手机一看,微信上一堆人发信息给我,先是一篇《微信应用号来了》,然后就是:“你怎么看?”

虽然之前曾经得到过消息说“微信应用号”会在年底发布,但没想到居然来的这么快,而且还改名叫“微信小程序了”(简称小程序)。已经无心打牌,赶紧完成一吃三后速度回到电脑前开始了持续几天的研究。而且这几天里各种相关资料都开始相继出现,内测用的开发工具也有破解版漏出了。


身边已经有不少朋友已经根据资料开始干活了,差不多有如下几类:

1)好好释放想象力,要是能在公测的时候做个有趣的小程序出来一炮而红那就赚大了

2)公司有一打的服务号,其实改成小程序会更合适(管它合不合适,改了再说!)

3)又是一轮洗牌的机会!那个公众号的功能是我先想到的但被别人抢了,这次我要在小程序里第一个做出来并做到第一名!

4)微信果然是互联网的“国务院”,新政策草案刚出立刻引起全行业的连夜研究。这么重要的关头,变革的前夜,我认为正确的做法是“战术上立刻响应,站略上不必着急”。不学习,不了解微信小程序是万万不行的,但立刻根据现在的资料,调整公司的方向,也有点为时过早。毕竟现在还在内测阶段,万一内测结果是“回炉重造”或则“大幅调整”(目前泄漏的资料已经处于正式发布的状态,应该不会大改了),那花在这里的时间都赔进去了还没地哭。所以我觉得对公司来说比较合理的做法是在立刻成立一个短期的临时小组,鼓励对小程序有兴趣的同学加入,一起开发几个有趣的小程序,主要目的就是学习。如果做出来的结果好还能赚一波眼球。等微信小程序正式公测了,再决策要不要把这个临时小组升级成一个正式的产品团队。


这几天通过目前公开的资料我已经对小程序的整体架构有了个初步的认识。我的风格一向是从架构和系统设计的视角做一些深度的,有观点的分析。现在终于可以回应朋友们的问题,谈谈我怎么看了。


微信小程序是什么?

官方这么说:

“我们提供了一种新的开放能力,让开发者可以快速地开发一个小程序。小程序可以在微信内被便捷地获取和传播,同时具有出色的使用体验”。


听起来非常美好,咱们具体一点,结合目前公开的信息和微信目前其它的开放形式对比一下吧


可以看到,腾讯还是非常有诚意的,这次在微信小程序上新开放的能力很多,不再是渐进式的演变而有一点像革命了。


小程序的入口在哪?

目前公开的资料里对大家最关系的入口问题只提到了小程序可以扫二维码打开,于是业界对小程序的入口有了这么几种流行的假设:


假设零:朋友圈,朋友可以把自己喜欢的小程序分享在朋友圈,看到了可以点击打开直接使用。

[配图1]


可能性:99%。小程序不能出现在朋友圈,流量从哪来?


假设一:出现在发现tab页面中,游戏下面(每个小程序占用一列),同时摇一摇也可以得到附近的小程序

[配图2]

可能性:80%。和一把腾讯的游戏挤在一起,不亏待你吧。


假设二:和当前的公众号、服务号类似,安装出现在会话列表

[配图3]

可能性:90%。新的开放能力和旧的开放能力用一样的入口不奇怪吧。


假设三:安装后和native app一样,直接出现在桌面

可能性:10%。和微信在同一级入口,腾讯同意Apple都不一定同意。


假设四:微信多一个小程序的tab


[配图4]

可能性:1%。多一个tab太丑了,而且小程序刚发布,不可能立刻就对微信的整体结构产生影响。


假设五:出现在一些内置流程中(比如和好友的聊天界面内,发朋友圈的界面(拍照后处理)

[配图 5]

可能性:1%。小程序和微信本体使用不同的框架技术开发,互相嵌套有困难。


微信小程序框架浅析


官方已经正式公开了小程序的开发资料(mp.weixin.qq.com/debug/),小程序的开发框架包含两大块内容,分别是:API 与 组件。官方的资料在组织和内容上都写的还不错,阅读体验也很顺畅,没看过的话推荐先简单的通读一遍。基本上有一定经验的前端开发都可以没有什么障碍的掌握目前资料里的内容,我就不去做入门性的介绍了,直接浅析吧。


先看框架的底层API部分。微信一直有一个贯穿的"JS-SDK"在不断演进。对比一下小程序的底层API的功能范围,和JS-SDK还是有很多相似的感觉,相信未来会在形式上达到统一(JS-SDK这名字也足够霸气,塞进去什么都不会觉得奇怪。不过JS-SDK的很多接口设计的实在不敢恭维,希望这次统一的进程也能重新修正下)。小程序的API部分由于可以跳出浏览器的框架,理论上肯定可以是JS-SDK的超集。


这里面我觉得比较有意思的地方有:

>>网络通信

只要目标服务器的域名在小程序配置的安全列表之类,就可以直接通信。不用考虑js的跨域问题了。

既然跨域都支持了,没准以后能像nodejs一样,直接在小程序里使用tcp,udp协议,并基于buffer有一定的二进制协议的开发能力。跳出HTTP协议的框架,对于IoT方向是很有想象空间的。


>>数据缓存

数据缓存接口的设计看起来和 HTML5里的localStorage基本上一样,本来没什么好说的。但文档里的一句话引起了我的兴趣:


“注意: localStorage 是永久存储的,但是我们不建议将关键信息全部存在 localStorage,以防用户换设备的情况。”


难道微信提供的数据缓存能力虽然不是永久的存储,但可以做到跟随用户账号而不是当前设备? 也就是说,不管用户怎么换手机,已安装使用过的小程序都能使用同一份缓存(不存在不登陆使用小程序的场景)?虽然微信自己的聊天记录跨设备漫游都没做,但这种app personal file cloud的支持,还是能在不增加开发的工作量的情况下,大幅提升用户体验的(作为一个steam的重度用户我已经完全离不开游戏存档的自动同步功能)。这也让我对小程序在云端的能力,开始有了一些初步的想象。


>>并不兼容一些常见js底层框架

小程序的官方QA里有一段话:

“zepto/jquery 会使用到window对象和document对象,所以无法使用”

这意味着所有基于HTML5的已有底层代码资产,并不能完全无缝的迁移过来。不过连jQuery这么常用的库都不能兼容还是有一点伤的。当然,现在用裁剪或兼容的方法,提供能在小程序平台运行的常见js底层库,短期内会很有市场。


MINA框架剖析

接下来我要解读微信小程序提供的界面部分功能,也是最令人兴奋的部分。一个小程序,必须基于MINA框架(从泄漏的资料里得知这个框架叫MINA,正式的资料里删除了这个名字,但为了后面行文方便,我会一直把小程序的应用框架称之为MINA)构建。一个典型的小程序的结构如下:

[配图7]


app.json 小程序配置:

小程序里一共包含哪些页面。

页面套在一个怎么样的 window里显示。

window是否需要支持多tab,支持的话每个tab的默认page是什么。

一些底层组件的默认参数。


app.js(可以理解为入口函数)

处理app的几个关键事件:onLaunch,onShow

定义了app级(可以在不同的页面之间共享)的数据的格式


app.wxss 公用样式表

每个页面的样式表,都是从这个应用级公有样式表继承下来的。


MINA一个最主要的核心概念是Page,一个Page是应用内可以导航到的最小粒度的界面。而如何构建Page是与大家过去猜测差别最大的地方。微信并没有使用HTML5,而是提供了一套新的设计。新的设计要求每个 Page由3个文件构成:


index.js :包含Page的逻辑处理代码

其中比较重要的就是定义Page的数据(wxml可以通过数据绑定机制直接访问)


index.wxml : Page的布局文件

随便从demo中选一个布局文件来看,其整体结构非常简介清晰,即使没有提供任何资料也大概能看出来表达了一个什么样的页面。

.wxml不算是完全的静态布局文件,还支持条件渲染和列表渲染。

.wxml使用{{}}语法来简单直接的支持数据绑定。

可以通过template的方法进行复用


index.wxss: 样式表

决定了在wxml中定义的各种组件最终应该如何显示。官方文档并没有列出wxss的selector语法和支持的style,只是说“具有CSS的大部分特性”,wxss样式表里也扩展了一些微信小程序专用的样式是属性。


Page的整体设计上有比较明显的“反应式”编程风格,相信有vue.js,angularJS,reactive.js开发经验的同学可以很快上手。由于没有内测资格所以没法在手机上测试性能,不清楚小程序的这套框架有没有反应式编程常见的性能问题。这个等公测后写个有10万条数据的列表,看看滚动流不流畅就知道了。


目前demo没有使用ES6,所以看起来没那么“现代化”,这也可能是因为小程序这个项目立项比较早的缘故吧。不过ES6是大势所趋,相信未来小程序会支持使用ES6开发。


一个基于MINA的小程序最后是如何跑起来的呢?

官方这么说:

“开发者写的所有代码最终将会打包成一份 JavaScript,并在小程序启动的时候运行,直到小程序销毁。类似 ServiceWorker,所以逻辑层也称之为 App Service。”



网上已经有不少人通过琢磨开发工具的实现的方法,做了比较深度的研究了,推荐阅读:

(微信小程序「官方示例代码」剖析【下】:运行机制 微信小程序「官方示例代码」剖析【下】:运行机制)

简单的总结一下:

wxml文件通过编译会得到html,wxss 文件通过编译会得到css,分离的各个页面的JS和App的主JS文件最终会打包在一起得到App Service。 开发状态下运行小程序,基于blink内核,每个html会加载一些moko js用来支持框架功能。生产环境在手机上估计是运行在一个专用,定制的浏览器内核中。




为什么是MINA?


业界对目前微信使用的UI框架,有两种截然相反的观点:

微信“小程序”带动HTML5发展 数据波来助力 微信“小程序”带动HTML5发展 数据波来助力-CSDN.NET

“微信小程序的本质说来就是一个HTML5应用”

“以后互联网的发展方向可能更偏重于HTML5”

而有的人又认为

我们真的需要“小程序”么?| HTML5老兵如是说 我们真的需要“小程序”么?

“微信虽然用了 HTML5 技术来做应用号(正式名称:小程序),但是它并没有真正用到 HTML5 的精髓——开放、互联,也就决定了它可能无法实现“微信OS”的最终野心。”


这两个观点是矛盾的,那么,到底那种观点是正确的呢?首先简化一下问题,微信小程序是基于HTML5开发的么?


通过分析小程序的运行原理,这个答案是明确的:小程序的开发过程会用到大量HTML5相关的技术,但并不是使用HTML5开发。有 HTML5经验的前端工程师学习微信小程序的开发相对会更容易一些。微信小程序的运行并不需要一个完整支持HTML5特性的标准浏览器内核,但也可以通过添加一些辅助设施,让小程序在个完整支持HTML5标准的浏览器上运行起来。


“由于框架并非运行在浏览器中,所以 JavaScript 在 web 中一些能力都无法使用,如 document,window 等。” 也就是说,一个已存在的HTML5页面,并不能通过自动转换工具变成一个合法的Page,而需要有工程师根据HTML5页面的功能,使用MINA框架再实现一次。

[配图 HTML5与MINA在功能上有交集,但并不相等]


搞清楚MINA和 HTML5的关系后,我们还是没有搞清楚为什么微信要提供一个新的MINA框架 。事实上这个问题是一个讨论设计的问题,所以要回答这个问题,需要具备一定的设计能力,而不是只是停留在研究MINA实现的层面。而设计能力,是一种比较稀缺的能力。


想要系统的提升自己的设计能力,简单的来说就是“多看+多想”,那么如何多想呢?我有一套还算完整的方法的,简单来说有如下几步:


首先,在研究一个新东西以前,先想想这个新东西,是为了解决什么样的问题出现的。问题要多提,往深了提,反复提炼,最后得到几个好问题。或则从一个问题,引申出一些子问题。很多时候只要问题提对了,设计就明白了大半。


下一步就是试着自己解决一下,回答一下自己提的问题,并比较不同的解决思路的优劣,形成一个对问题解的标准。比如说问题是“如何在一个超长文本中查找子串?” 那么对问题的评价标准就可以是查找速度,以及查找过程中的内存占用。


接下里就是看别人是如何解决这些问题的了。如果和自己的设计差不多,一边窃喜一边开始按自己预先设计的评价标准对别人的设计的好坏进行判断。如果是自己完全没想到过的解法(这通常会出现在第一次接触某个领域问题),可以按图索骥的补充一些基础知识,再回来看。如果这个领域或解法非主流到不是常见范式,那么可以安下心来好好搞清楚,想明白。 这样带着问题研究设计,才能有效的提高自己的设计能力。


介绍完套路后咱们回到正题:我们如何来评价微信小程序选择MINA框架?让我来持续提问吧。


第一个问题:“为什么微信小程序不使用HTML5而是使用MINA来构建Page?”

不用HTML5我可以提供一个非技术答案:微信需要通过这种方法来转化开发者,这些开发者未来会逐渐演变成“微信OS平台”的忠实开发者。其实开发者通常都有患有“斯德哥尔摩综合症”,一旦在一个平台上投入了智力资源进行学习,就会开始下意识的维护这个平台(比如看不到平台的缺点,只看到平台的优点)。如果使用HTML5作为开发方式,那么现在小程序聚拢的开发者都是为了流量来的,并没有投入额外的学习成本,对平台不够忠诚。而微信要成为OS是一个长期的演变过程,那么现在就要通过要求学习一个新的开发框架的方法开始多转化一些忠诚的开发者。


当然是不是这个原因也只有张小龙自己知道了,这是一个揣摩动机的答案,所以没有评价标准。问题终结。


为什么不用HTML5的技术答案可以是非常庸俗的。毕竟业界对于HTML5技术的优劣讨论已经持续了一段很长的时间了。但基本上,大家认为HTML5的主要缺点集中在性能上:同样的交互,用HTML5实现需要更多的系统资源,也可能会不够流畅。同时,应用还需要集成一个非常巨大的浏览器内核。


这个答案尽管能让大部分人满意,但实际上是非建设性的(这些对HTML5性能的结论,是别人告诉你的)。大家一边相信HTML5的美好前景,一边把对性能问题的解决寄托于几家传统的浏览器厂商。按我们的套路,这个性能问题再往深了问是这样的:“渲染指定页面最少需要多少资源?”,“在当前硬件水平下,渲染指定页面最快需要多少时间?”,“实现一个完整支持HTML5标准的浏览器内核,需要大概多少代码?”。要回答这些问题就需要了解浏览器的实现了,这不会是一件容易的事情,在阅读浏览器的实现的时候,肯定会持续提出针对HTML的设计问题。最终你会对浏览器厂商什么时候能解决性能问题,得到一个更合理的预期:至少在5年内,HTML5的性能是不够的。


虽然SAY NO的理由,有一条就够了。但如能从其它角度思考一下为什么不是HTML5,可以得到一些更有建设性的答案。


第二个问题:“MINA作为一个新框架,为什么会设计成现在的样子?”

可以肯定的是,这是MINA的架构师在综合了多个因素后,拿出来的一个自己最满意的答案。所以这是一个非常有建设性的问题,思考这个问题的时候,就开始逐步代入MINA的架构师视角了。


让我们一起进入MINA架构师的角色,首先在否决了HTML5后,要设计一个什么样的框架来支持小程序的交互开发?第一步就是要给这个新框架提一些基础性的目标与需求。


这是一个现代化的框架,在最终表现力上要足够好。

小程序跑在微信里,所以必然是和android,iOS的具体平台特性无关的。

要面向更多的非专业开发者,所以学习门槛要低。

大规模的专业团队进行团队开发时,能有足够的工程支持。工程支持包括:
模块化
代码易于长期维护和修改。这意味着基于框架的实现具体需求的结果要足够清晰,好读。

可复用性设计。

小程序不需要安装就可以快速开始使用,只需要加载必要的资源就可以尽快展现用户需要的页面。


进一步思考这些需求该如何解决,并对不同的解决方案进行评价需要的领域知识非常多,已经超过了本文的讨论范围。我在这里要做的只是带你入门,让你开始思考设计问题就够了。这也是本文的核心目的:学会对新技术,新设计进行独立的分析和判断。至于结果么,现在小程序还处于一个早期的状态,等公测了之后在下结论也不迟。



微信小程序的未来?


虽然现在小程序开放的功能并不丰富,处于一个早期的状态,但结合上面的观点去看微信小程序的设计,还是能从中读到许多远大的理想。而微信的核心愿景之一是“连接一切”,没准小程序是腾讯实现这个愿景道路上的重要一步。有超过7亿用户的微信如果成为一个新的平台,具有不可忽视的能量,下面让我来对小程序的下一步动作做一些无责任的预测吧。


假设一、微信小程序未来会解决应用内搜索的问题

目前小程序规范的页面结构很方便实现应用内搜索。以后使用微信的搜索功能可以直达小程序内部的某个特点内容页面。

这种规范的设计也方便实现小程序之间的互相访问,可以通过一个类似wxapp://appid/pageid/的URL直接导航到另一个小程序的某个特定页面。这是App时代的超连接系统,App的信息孤岛也许就此打破。


假设二、微信小程序会从本地数据读取开始,进化出一定的云端API.

现在小程序只提供了前端的开发功能,但从整体逻辑上已经包含了应用的上传,审核,发布流程。

以后腾讯也许会为小程序提供托管服务(qcloud.com/act/event/yi),让应用开发者可以用更少的精力完成一个完整小程序的开发,而不需要去管服务器申请,后台开发,服务器运维等反繁琐的工作,进一步降低一个真正小程序的开发门槛。我相信微信一定有团队在为这个方向努力,但最终实现目标需要更有创造力的云端API设计,这是需要有大智慧的工作。


假设三、使用小程序连接一切

我并不认为小程序只是一个体验更好的服务号。张小龙说小程序是“触手可及”,“用完即走”,“无处不在”的。那么什么场景会需要这种能力? 我觉得“有复杂程序的低频商业行为”会有这种需求。举两个实际的例子:


例1:有一间智能会议室,入口处有一个二维码。会议室的使用者扫描后可以打开一个小程序,通过这个小程序可以更好的访问、控制会议室的各种设备,比如灯光,窗帘,幕布等。


例2:去体检,体检表上有个二维码,扫描后打开一个小程序,通过这个小程序可以更好的引导用户自助完成自己的体检项目。


这两个场景的需求能通过小程序解决,意味着小程序的种类极大丰富,硬件厂商对微信生态的极大支持。我们可以通过小程序简单方便的进入各种陌生的环境,让生活更加智能。未来已经悄悄敞开了大门。


而如何更好更快的探索小程序的可能性,也将是我接下来创业的方向。我将以火速移动技术顾问的身份,和小伙伴们一起从微信小程序开始,去探索移动Web的可能性。

感谢各位关心。

通过网页代码调用原生的api/控件,然后一堆限制,始终不理解为什么这些程序员不自己写个移动网站,非要钻微信的笼子,没有性格没有下限。
瞎猜的:
用Native抹平了系统间的差异,搞套DSL把系统的API暴露给前端开发。
可以理解为没有编译过程的React Native/Weex,有WebAPP的灵活性,又有接近Native的性能。
用js调用android和ios底层功能,用html5展示界面。性能比不上原生app
mishen - whatsns产品经理
6楼-- · 2016-11-06 18:59
作者:phodal
链接:zhuanlan.zhihu.com/p/22
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

本来想的是昨天晚上写这篇文章的,后来昨天在写一个Cordova上的iOS插件的时候各种不顺。对接的第三方SDK不给力,于是六点多回到家的时候,我就就开始娱乐了,哈哈哈~~

其实这篇文章应该算是一篇拾遗。

从map组件说起

在今天公布的开发文档里,我们知道使用一个地图组件的时候是这样子的:


<map longitude="23.099994" latitude="113.324520" markers="{{markers}}" covers="{{covers}}" style="width: 375px; height: 200px;"></map> 

在之前的文件里,我们提到过这个文件是wxml文件,然后我们要用wxcc将其转换为virtual dom中的方法,如:


./wcc -d map.xml 

它就会返回一个js的方法,如:


/*v0.7cc_20160919*/ var $gwxc var $gaic={} $gwx=function(path,global){ function _(a,b){b&&a.children.push(b);} function _n(tag){$gwxc++;if($gwxc>=16000){throw enough, dom limit exceeded, you don	 do stupid things, do you?};return {tag:tag.substr(0,3)==wx-?tag:wx-+tag,attr:{},children:[]}} function _s(scope,env,key){return typeof(scope[key])!=undefined?scope[key]:env[key]} ... 

插播一句:上面有一个count,很有意思$gwxc > 16000,这个就是dom数的count。超了就来个异常:enough, dom limit exceeded, you dont do stupid things, do you?,中文意思就是:你个愚蠢的人类,你是一个前端开发人员吗?

随后,在浏览器里调试一下:


JSON.stringify($gwx(map.wxml)(test)) 

在小程序中是要这样调用的:


        document.dispatchEvent(new CustomEvent("generateFuncReady", {             detail: {                 generateFunc: $gwx(map.wxml)             }         })) 

就会返回下面的结果:


{     "children": [         {             "attr": {                 "covers": "",                 "latitude": "113.324520",                 "longitude": "23.099994",                 "markers": "",                 "style": "width: 375px; height: 200px;"             },             "children": [],             "tag": "wx-map"         }     ],     "tag": "wx-page" } 

看来这个名为wx-map的标签就是微信下的map标签,它是wx-page的children。然后让我们在WAWebview中搜索一下,就会发现一个很有意思的代码:


{     is: "wx-map",     behaviors: ["wx-base", "wx-native"],     template: <div id="map" style="width: 100%; height: 100%;"></div>,     properties: {         latitude: {type: Number, reflectToAttribute: !0, observer: "latitudeChanged", value: 39.92},         longitude: {type: Number, reflectToAttribute: !0, observer: "longitudeChanged", value: 116.46},         scale: {type: Number, reflectToAttribute: !0, observer: "scaleChanged", scale: 16},         markers: {type: Array, value: [], reflectToAttribute: !1, observer: "markersChanged"},         covers: {type: Array, value: [], reflectToAttribute: !1, observer: "coversChanged"},         _mapId: {type: Number}   } 

它的behaviors中有一句:wx-native,这莫非就是传说中的native组件:

顺便再看一个video是不是也是一样的:


{     is: "wx-video",     behaviors: ["wx-base", "wx-player", "wx-native"],     template: <div class="container">
    <video id="player" webkit-playsinline style="display: none;"></video>
    <div id="default" class="bar" style="display: none;">
      <div id="button" class$="button {{_buttonType}}"></div>
      <div class="time currenttime" parse-text-content>{{_currentTime}}</div>
      <div id="progress" class="progress">
        <div id="ball" class="ball" style$="left: {{_progressLeft}}px;">
          <div class="inner"></div>
        </div>
        <div class="inner" style$="width: {{_progressLength}}px;"></div>
      </div>
      <div class="time duration" parse-text-content>{{_duration}}</div>
      <div id="fullscreen" class="fullscreen"></div>
    </div>
  </div>
  <div id="fakebutton"></div>,     properties: {         _videoId: {type: Number},         _progressLeft: {type: Number, value: -22},         _progressLength: {type: Number, value: 0} } 

好了,你那么聪明,我就这么说一半好了,剩下你自己去猜。

可以肯定的是:

  • map标签在开发的时候会变成HTML + CSS
  • map标签在微信上可以使用类似于Cordova的形式调用 Native组件

再接着说,virtual dom的事,回到示例代码里的map.js:


Page({   data: {     markers: [{       latitude: 23.099994,       longitude: 113.324520,       name: T.I.T 创意园,       desc: 我现在的位置     }],     covers: [{       latitude: 23.099794,       longitude: 113.324520,       icaonPath: ../images/car.png,       rotate: 10     }, {       latitude: 23.099298,       longitude: 113.324129,       iconPath: ../images/car.png,       rotate: 90     }]   } }) 

js里只放置了data,剩下的都是依据上面的值变动的observer,如:

  • _updatePosition
  • _hiddenChanged
  • latitudeChanged
  • longitudeChanged
  • scaleChanged
  • coversChanged
  • ...

这种代码的感觉比React更进了一步的节奏,本来你还需要编码来观察state,现在只需要state变动了就可以了。。。23333....,你们这些程序员都会被fire的。

好了,这里差不多就这样了~~。

重新审视WXWebview.js

于是,我重新逛逛WXWebview.js,发现这个文件里面不只有component的内容,还有:

  • reportSDK
  • webviewSDK ??
  • virtual_dom
  • exparser
  • wx-components.js
  • wx-components.css

等等,你是不是已经猜到我在说什么了,上一篇中我们说到了PageFrame:


  <!-- percodes -->   <!--{{WAWebview}}-->   <!--{{reportSDK}}-->   <!--{{webviewSDK}}-->   <!--{{exparser}}-->   <!--{{components_js}}-->   <!--{{virtual_dom}}-->   <!--{{components_css}}-->   <!--{{allWXML}}-->   <!--{{eruda}}-->   <!--{{style}}-->   <!--{{currentstyle}}-->   <!--{{generateFunc}}--> 

在之前的想法里,我觉得我必须要集齐上面的SDK,才能招唤中神龙。后来,我看到了这句:


isDev ? {         "<!--{{reportSDK}}-->": "reporter-sdk.js",         "<!--{{webviewSDK}}-->": "webview-sdk.js",         "<!--{{virtual_dom}}-->": "virtual_dom.js",         "<!--{{exparser}}-->": "exparser.js",         "<!--{{components_js}}-->": "wx-components.js",         "<!--{{components_css}}-->": "wx-components.css"     } : {"<!--{{WAWebview}}-->": "WAWebview.js"} 

如果不是开发环境就使用WAWebview.js,在开发环境中使用使用xxSDK,那么生产环境是怎么回事?如果是在开发环境会去下载最新的SDK,好像不对~~,哈哈。。

我猜这部分,我需要一个内测id,才能猜出这个答案。

有意思的是,IDE会对比version.json,然后去获取最新的,用于预览?


{   "WAService.js": 2016092000,   "WAWebview.js": 2016092000,   "wcc": 2016092000,   "wcsc": 2016092000 } 

上面已经解释清楚了WAWebview的功能了,那么WAService.js呢——就是封装那些API的,如downloadFile:


uploadFile: function (e) {     u("uploadFile", e, {url: "", filePath: "", name: ""}) && (0, s.invokeMethod)("uploadFile", e) }, downloadFile: function (e) {     u("downloadFile", e, {url: ""}) && (0, s.invokeMethod)("downloadFile", e) } 

这一点上仍然相当有趣,在我们开发的时候仍然是WAWebview做了相当多的事,而它和WAService的打包是分离的。

那么,我们从理论上来说,只需要有WAWebview就可以Render页面了。

块级元素用了本地组件绘制,普通组件兼容WEB js封装底层 提供接口 类似Hybird App 比普通web APP性能好 开发飞机大战之类的社交小游戏 妥妥的 性能没问题。
推荐下我的前端专栏:前端动态 - 知乎专栏
只有干货...
根据小程序开发文档-框架(mp.weixin.qq.com/debug/)部分,可以从微信小程序提供的开发接口上看出:
1. 提供了JavsScript运行环境,由JavaScript编写的业务代码完成逻辑层的处理
2. 通过数据传输接口(注册Page时的data属性及后续的setData方法调用)将逻辑层的数据传输给视图层
3. 视图层由WXML语言编写的模板通过“数据绑定”与逻辑层传输过来的数据merge成展现结果并展现
4. 视图的样式控制由WXSS语言编写的样式规则进行配置

再分别来看这4点各自的细节问题:
1. 提供了JavsScript运行环境,由JavaScript编写的业务代码完成逻辑层的处理
JavaScript运行环境是什么?
开发文档Q&A(mp.weixin.qq.com/debug/)中这句已给出,JS运行环境是在JsCore里:
为什么脚本内不能使用window等对象

页面的脚本逻辑在是在JsCore中运行


2. 通过数据传输接口(注册Page时的data属性及后续的setData方法调用)将逻辑层的数据传输给视图层
数据在逻辑层与视图层间如何传输?
视图为纯native渲染,故位于native端。
而逻辑层如上所述,是跑在JsCore中的JavaScript代码。
有了JsCore,微信小程序框架的native端与js端就可以通过JsCore来相互通信了。于是,微信小程序框架的native端与js端可以约定好通信协议/规范,再把js端通过此通信协议/规范与native通信的部分封装并暴露接口为API(最上层的传输或说设置数据的API也就是上面说的注册Page时的data属性与后续的setData方法),这样逻辑层的业务代码就可以实现向视图层传输数据了。
(对native其他API的调用也用类似的方法即能走通)

3. 视图层由WXML语言编写的模板通过“数据绑定”与逻辑层传输过来的数据merge成展现结果并展现
视图层与数据如何merge为展现结果并展现?
首先看WXML语言提供的接口,发现它:
  1. 类似于html/xml,用标签方式来描述视图
  2. 类似angular/vue,通过指令(标签的特殊属性)与双大括号来实现模板的增强功能,使模板与数据merge为结果标签
    1. 但细看发现,指令其实很简单,只提供了用于循环列表的wx:for指令,与用于控制逻辑的wx:if,wx:else,wx:elif指令
    2. 双大括号内支持简单的表达式,表达式中的变量即逻辑层输入的数据
  3. 每次逻辑层更新数据,视图层会相应更新merge并更新渲染
考虑最简单的情况,要完成这3个功能,大致可以通过做如下事来完成:
native端读取WXML模板文件,再根据逻辑层传来的数据将其中的指令与双大括号处理解析(可根据大括号表达式从数据中取值并计算,再以对表达式值进行循环与判断便可相应解除wx:for,wx:if指令),生成与数据merge后、可以表征最终展现内容的标签串,
再以解析xml的方式解析标签为带有属性的节点树,并对应节点树中各节点相应创建native中的视图元素(可能为系统组件、也可能为微信框架中的视图组件)、设置相应属性、维护为正确的父子关系即可。
逻辑层数据更新时,也更新相应属性即可。
当然实际处理中,要考虑的因素要多许多,也会做许多优化,但基本思路应大致如此。

4. 视图的样式控制由WXSS语言编写的样式规则进行配置
样式如何匹配与设置?
构建出各视图元素后,仍由native读取WXSS文件,用简单字符串匹配即可将其解析为一对一对的"选择器-规则"对,规则内即为属性键值。之后再对各视图元素与"选择器-规则"对中的选择器进行匹配,匹配成功设置相应属性值(还要考虑全局样式与页面样式及style属性样式中的优先级)即可
如何使用css样式对native元素进行布局?
最基本的flex布局可以由facebook的css-layout来完成(GitHub - facebook/css-layout: A subset of CSS (specifically flex-box) re-implemented as a stand alone project for use primarily on mobile. Used by react-native)

另外,事件方面,native接收到用户事件后,必要时通过JsCore反向与其内运行的js进行通信,将事件数据传递给js端的框架,再由js端框架调起相应回调即可。

另有一些细节可参见:微信小程序开发API调研 - 吕晟的文章 - 知乎专栏
欢迎讨论,望轻拍 : )

一周热门 更多>