专栏名称: CSDN
CSDN精彩内容每日推荐。我们关注IT产品研发背后的那些人、技术和故事。
目录
51好读  ›  专栏  ›  CSDN

微信小程序的编程模式

CSDN  · 公众号  · 科技媒体  · 2017-01-10 09:53

正文

作者简介: 范怀宇,轻芒联合创始人,毕业于清华大学,前豌豆荚技术负责人,专注于移动开发十余年,曾出版《Android 开发精要》。爱研习好代码和设计,相信好的产品能改变生活,好阅读乐分享。
责编: 唐小引 ,技术之路,共同进步。欢迎技术投稿、给文章纠错,请发送邮件至 [email protected]
本文为 《程序员》2017年1月期 原创文章,未经允许请勿转载,更多精彩文章请订阅 2017 年《程序员》

导读: “轻芒小程序+”是由轻芒团队提出的小程序解决方案,它将替内容创业者免费搭建属于自己的微信小程序。在进行“轻芒小程序+”和其他小程序应用开发的过程中,本文作者与其团队对当前正火热的小程序开发有了更为深度的理解与认识,进而有了本文。(这里还有一篇满载真诚的 微信小程序开发 干货,点击查阅。)


从小程序诞生伊始,就有很多人开始研习其机理与特点,从源代码或整体架构的角度已经有很多不错的文章会令人受益。但理论是一回事,真正理解小程序,还需要实践,才能进一步理解其背后的想法,与已有平台的异同,以及如何去适应它,做出更有趣的小程序。

理解开发平台的特性,一个不错的角度就是从编程模式入手,看在这个平台上开发,需要如何书写和组织自己的代码,进而搞清楚三个问题:

  1. 数据如何获取;

  2. 界面如何呈现;

  3. 交互如何传导。

换而言之,就是从 MVC(Model-View-Controller)的视角去拆解这个平台的特性,从而理解其开发有何特点。

数据如何获取

程序的本质,可说就是数据的呈现和加工。所以,看一个客户端开发平台的基本能力,首先就要看能把哪些数据放在上面处理,有哪些局限?如果缺少了必要的数据获取方式,那对于开发者而言,巧妇也难为无米之炊。

从这点看,小程序提供的数据获取方式非常丰富,大概涵盖:

  • 通过 HTTPS 请求去服务端获取数据。 支持 HTTPS 是最基本的,小程序对 HTTPS 有限制,除了要求通信协议是 HTTPS,出现的域名必须提前预设之外,还将应用层协议限定到了 JSON 格式下。这一点,可能比任何一个已有客户端平台都更为严苛。站在小程序的平台角度来看,通过这样的协议规定,对应用中流动的数据有了更强的管控能力;而对于开发者而言,则需要花些时间去调整自己的服务协议以便适应小程序的要求。

  • 可以在本地文件系统上存取数据。 小程序提供了丰富的 API 供开发者在手机系统上存取文件。可用本地文件来做缓存、状态记忆等,为开发提供了便利。

  • 可以读写设备中的一部分信息。 小程序开放了一些 API,帮助开发者获得设备上的基本信息,比如手机型号、屏幕尺寸、网络状态等。较为有价值的是可以选择获取手机上的图片等多媒体文件,这给做图像应用提供了可能;并且,它还提供了罗盘、重力感应器、地理位置等信息,对开发者理解用户所处的环境大有裨益。

从上面的介绍不难看出,小程序中的数据获取方式,和一般浏览器提供的相仿(也就是和 HTML5 应用能获取的信息),比原生的客户端更局限一些,但对于绝大多数的应用而言足够用了。

除此之外,小程序提供了微信生态中的一些数据,比如账号信息等。这对于微信庞大的生态而言,只是非常小的一部分数据,但却是开发小程序应用中最值得利用的数据。

举个例子,在其他平台上,如果想要获取微信的账号信息,需要通过一次用户授权。假如用户暂时不想提供,则会使程序呈现“未登录”状态,给整个服务的展开带来困难。而在小程序中,只要用户点开,就意味着完成了授权,开发者可以直接读取到小程序的账号信息,并同步到自己的服务端作为该用户的身份标识,从而实现“始终登录”的状态,使得后续服务可以更好地提供。

一份可行的示例如下:

// 先调用登录接口,获得请求码wx.login({
    success: function (res) {
        // 获取到请求码,继续请求用户的基本信息
        var code = res.code
        wx.getUserInfo({
            success: function (res) {
                // 获取到了加密的用户信息,去服务端解密并存储
                var userData = res.encryptedData                var iv = res.iv
                wx.request({
                    url: 'https://my_account/...',
                    data: {
                        code: code,
                        user_data: userData,
                        iv: iv
                    },
                    success: function(res) {
                        // 在服务器上,解析并生成自己的账号验证信息
                        var user = res.data.user                        var token = res.data.token                        // 并且还可以存在本地存储上,供下次打开使用
                      wx.setStorage({
                            key: 'my_token',
                            data: token
                      })
                    }
                })
            }
        })
    }
});

界面如何呈现

小程序刚发布的时候,一片人开始惊呼 HTML5 的时代就要到来了,因为小程序在界面层使用了 HTML/CSS/JavaScript 这套 HTML5 的技术栈。但很快,随着聪明的程序员们对小程序的理解进一步加深,就发现小程序所说的 HTML/CSS/JavaScript 和 HTML5 中的完全不是一回事,其差异基本等同于 Java 和 JavaScript。

在小程序中,和 HTML 对应的是 WXML,保留下来的只有 HTML 的概念,而传统的

标签都完全被抛弃了。和 Facebook 的 React 类似,小程序引入了自己的 HTML 标签,它和

这样的语义标签不同,小程序中的标签更像是传统客户端开发中的组件(或者叫控件),每个组件都有自己背后的职能和使用方式。比如:如果需要展示图片,就只能用标签,其他的都无法承载。而如果需要提供可选的文本,则只能使用 标签等。

这样的方式带来最大的问题就是传统的 HTML 页面都无法在小程序中呈现(而小程序正好,没提供类似 WebView 的客户端控件)。比如有大量的内容网站,其文章内容都是存储为一个 HTML 片段,无法直接呈现在小程序中。如果需要展示,一个思路是构建中间服务,将 HTML 转译成一种更简单利于渲染的中间格式数据,然后,在小程序端把中间格式的数据转换成小程序的标签进行呈现。我们在做“轻芒生活”的时候,正好设计并实现了一个转义服务,将任意一个 HTML 页面转换成中间格式(内部名是 RAML),解决了内容性 HTML 页在小程序上的呈现问题,如图 1 所示。

图 1 在小程序中呈现 HTML 内容页


和 HTML 相比,小程序的 WXSS 算是比较完整地保留了 CSS 的特征,这一点还蛮出乎意料。WXSS 在语义上最大的不同,一是在于它支持了相对尺寸单位 rpx(responsive pixel),每 750rpx 等价于当前设备的屏幕宽度,它的引入,把那种繁复的屏幕尺寸适配变得简单了不少。而和 CSS 的另一个不同是它更像传统控件样式用法,不支持 CSS3 那么多的选择器,使用中更多的是一个控件一个 class。

小程序中虽然支持 ES6 标准的 JavaScript,但窗口级的 JavaScript 却完全被废弃掉了,开发者无法用 JavaScript 去调用 window、document 对象来修改界面元素完成逻辑。小程序中的 JavaScript 其实直接对应 Node.js 的用法,用来完成后台业务逻辑,而不是直接控制交互。小程序的这个设计,使其可以用到 Virtual Dom 的方式来渲染界面,让界面数据更新时的性能优化成为可能,但付出的代价就是少了窗口级 JavaScript 的那层胶水黏合,使得很多功能的开发变得极其呆板和繁复。







请到「今天看啥」查看全文