微信小程序从入门到重新入门
由于最近参与项目的缘故,需要了解一下微信小程序的整个开发与上架流程,于是去看了几天官方文档之后决定从零开始写一个小程序。
微信小程序完全是依托于微信平台才能发展到如此规模。与微信小程序相似的业务其实在之前不知道涌现出多少,所以当微信公布要做小程序时几乎所有人都不看好,而经过多年的迭代开发现在微信小程序在加上微信小游戏,已经开始渐渐深入大众日常。而这其普通人最为熟悉的应该是各类商城与点餐小程序,并且可以看出这类小程序已经形成一定的平台规模。
目录
一、现状
从个人入门现状来看,微信小程序本身限制很多,并且其表现效果并不尽如人意(关于这点在重新入门章节再做说明)。但是目前的现状是小程序日活1.7亿,月活4.3亿参与开发者100多万,乐观预测18年小程序总量将超过120万,从数量上超越AppStore应用总和。同时小程序用户日均使用时长7.5分钟,用户在使用微信是有1/12的时间在使用小程序。
值得注意的是小程序本身的定位正在发生变化。从微信公众号关联小程序开始,又到微信小程序反向引流公众号。小程序的入口已经渐渐从发现转向更多依赖场景,与公众号产生强关系,更加偏向用户使用记录的类别。不可避免的单纯的工具类小程序使用时间在持续降低,同样附近小程序这个场景的流量也在持续减少。
同时在我们日常生活中会发现非常多的模板类小程序,比如商城和餐饮行业。不难发现某些行业已经出现针对性的微信小程序解决方案,甚至不少商家都是被这些方案企业吸引去使用小程序这个平台,但是作为一个新的产业和流量入口显然这样盲目进入是没有多少意义的。所以可想而知针对这种平台与行业的解决方案随着更加深入的发展,必定会出现更加细分的行业去做小程序入口的推广和运营类工作。
当然随着小程序技术上的发展以及微信这个独立性相对较高的平台逐渐演变,我们有必要相信在可预见的未来小程序平台必定发展非常迅速。同时小程序相关行业也刚刚开始兴起,无论是技术还是产品运维人员都是一个绝佳的入场机会。
二、上手
作为技术人员尝试新技术最直接有效的方法就是使用这项技术实现一个功能。
由于最近调整了作息时间,导致每周总是忘记看剧。我个人的习惯是除了非常优秀的剧集,否则一旦积压起来就不想去看,因为我觉得专门抽出一大段时间补各种番剧是非常浪费时间的行为(笑)。也正是因为此我决定写一个番剧时间表用于提醒晚上回家看哪些番剧。
1. 准备工作
如果有移动端开发再加上前端开发经验,那么我可以直接说微信小程序几乎没有难度。当然如果有后端开发经验那你甚至只看文档就能做出一个小程序。好在这几个方面经验我都有一些。不过如果你没有做过后端也没关系,只要有一些前端知识上手小程序开发也是没有什么大问题的。所以在入门部分我就以一个稍微有点前端经验的开发者角度进行开发说明,重新入门部分算是进阶版吧是做一个稍微像样的小程序的入门。而对于整个技术栈与解决方案,之后会专门从较为专业的开发者角度进行说明。
微信小程序可以理解为一个离线的html程序包,作为基础框架采用本地读取与渲染,数据通过http接口从远端服务器拉取,这与现在谷歌提倡的PWA较为类似。如果在移动端比如android,本地放置一个html页面使用webview直接读取算是非常常用的需求了。无论是iOS还是Android都有穿透webview的通信方式,其实现效果就是web页面上的Javascript
脚本可以与本地代码OC
或者Java
进行调用和回调。所以理论上写好了本地框架其它所有功能都可以使用与平台无关的语言,如JavaScript
和Html
来实现,并且使用css
样式表控制UI展示效果。同时最大的好处是,使用框架层抹平平台差异,上层可以实现代码移植。现实确实是这样的,从比较彻底的ReactNative
到更加友好的Weex
再到做基本通信封装的Cordova
,差不多都是这个思想。
微信小程序的特别之处就是这个webview容器是完全自己定制的,在此基础上连html
标签都是自己定制。但是可以相信的是这只是在开发者层面做了隔离,下层依旧是符合标准的东西。随便一提如果是android开发者对系统webview存在怨言的话,可以使用腾讯的X5Webview
其提供了各类行业标准的统一规范性实现,为webview
相关开发减少了很多麻烦。
2. 架构
架构问题就如同我上面在准备工作中说的那样,理解成本地应用直接在webview中打开缓存的html程序包。而关于这个程序包的下载,缓存与版本管理都由移动端微信客户端实现。所以微信本质是小程序的本地运行环境,我们对于本地功能的使用都是通过微信来实现。所以我们不难发现微信小程序给我使用的API几乎除了网络都是本地API,即访问本地功能。
当然了如果习惯前后端分离的前端工程师,这也很容易理解。即我们只有和后台通信的几个API,其余功能完全自己处理,感觉上又从BS走向CS的感觉。和移动端刚兴起时候相比解决了非常好的跨平台问题,以及有微信这个资源和平台,这是非常重要的。
后端也是使用前后端分离的开发思想,传统的服务端直接渲染页面的方式就有问题了。其实这也是更好的让开发人员专注于自己负责的业务,专业的工作交给专业的人来做。
三、后端
小程序后端大致有两个选择方向,腾讯云的小程序解决方案或者完全自己搭建。值得注意的无论是使用腾讯云专门的小程序方案还是自己解决,都避不开两个重要的因素,https证书和网站备案。这其中https是小程序强制规定,备案是小程序后台强制要求,缺一不可。
非接口请求不受此限制,如图片资源的地址链接。
1. 自己搭建
自己搭建就没有过多需要说明的,主要是提供基本的REST接口供微信小程序的wx.request
使用即可。而其中的类似于websocket
功能在这个入门文章中也不做过多说明。
自建服务器的选择性就多了,但是至少要有一个域名和主机。好在现在各种云服务提供商比如阿里云,腾讯云华为云等都提供了不错的方案,甚至有专门的app和游戏类后端方案。而http是证书和备案都有帮助通道,提供了非常多的便捷。
如果你现在已经有在线的网站或者移动端APP,那么只需要公用现有接口或者专门为小程序设计出API接口即可。稍微大型的企业可能会使用Spring/Spring-boot或者全套的SpringCloud方案,而一个小公司php甚至pyhon以及node.js就能满足需求了。而腾讯小程序配套方案在服务端仅提供php和node.js两种环境,所以商业应用请酌情选择。
2. 腾讯云小程序方案
腾讯云的小程序方案后端会提供几个月的试用期,这对于个人试手还是很不错的,不过考虑的备案问题也请酌情考虑。
另外腾讯云小程序的方案只允许通过特定通道上传代码,并提供一个Mysql数据库以及phpadmin对外接口,所以它并不是一个可定制的服务端主机,也不是一个可控的VPS。所以如果你把mysql折腾死了还需要腾讯云的工作人员帮你恢复。
如果你使用腾讯云提供的小程序配套方案,那么它会提供一个直接可用的免费开发环境,并且生产环境与这个开发环境也是高度的相似,迁移起来非常方便。但是限制非常的多,所以如果你想做小程序是一个产品的话还是选择操作性更强的云主机。
官方推荐的node.js服务端环境wafer2,实际上是著名node.js框架koa2的修改版
如果你的服务端并不需要多么复杂的业务,也没有那么夸张的访问量与并发问题的话,我还是比较推荐wafer的。毕竟小程序的开发环境本质上也算是node.js了,服务端与客户端都是node.js环境算是比较统一吧。另外一点就是node.js开发服务端真的是非常的简洁,当然这还是要看业务量的。
四、小程序
单说小程序的开发实际上还是有一些门槛的,这主要得益于前端这么多年的发展,尤其是近几年的快速发展。虽说时下众多前端技术和框架发展的如火如荼,但是这些其实很早就出现了。AngularJS
诞生于2009年,backbone.js
是2010年,React
和Ember
是2011年,Vue.js
是2014年。从Ajax
的出现到谷歌V8
,再到node.js
以及W3C对于Web标准的推进,当前的前端技术的发展虽说并没有本质的变化,但是前端工程师已经感觉到技术的突飞猛进与日新月异。甚至夸张的说前端每天都是新的框架新和库诞生,他们都声称可以取代某某某,声称提高多少效率解决多少问题。
这里可以直接的说如果没有用过react
或者vue.js
这类库,那么小程序的开发首先从认识上就有一点难度。当然了如果不在意也是没问题的,但是一些更为便捷的工具可能就无法更好的使用了,这一点会在重新入门的章节中尽心介绍。
那么接下来我就以一个对vue.js
有些了解的开发者视角介绍小程序的开发。
1. 入门
首先在微信公众平台注册成为开发者。值得注意的是微信公众平台一个账号只能作为一个主体角色,即微信公众号,微信小程序与账号是一对一的(但是一个小程序可以允许有多个开发者)。接下来看微信小程序的开发文旦,包括前置的简易说明、框架、组件、API、工具等。
先不说一些比较特殊的功能,入门只需要了解一下数据绑定与页面渲染即可。再加上一些页面跳转,模板与事件基本上简单的小程序都可以了,毕竟常规的小程序只是请求数据在本地展示而已,如果只是做一个离线的应用,那连服务器请求也不需要了。
1.1 代码结构
如果使用wafer2框架的话,整个小程序文件结构如上图,包括微信端小程序/client
与服务端框架/sever
。
全局配置
在根目录默认包括app.js
、app.json
、app.wxss
、config.js
几个文件,其他分别是:
app.js
:小程序声明,全局变量声明,全局事件声明。使用App({})
设置,可以在此JSON对象中设置全局数据,并在其他位置使用getApp()
来获得,主要的还是使用里面的生命周期方法,如整个小程序的显示与隐藏,第一次启动,全局错误捕获等。app.json
:JSON格式的小程序全局配置文件,主要使用"page":[]
声明类似于路由结构的文件导航地址。此外还有如"window":{}
结构设置全局背景色,小程序标题,下拉刷新,导航栏信息等。app.wxss
:即全局样式表,可以简单理解成全局css文件。使用@import
+ 相对文件路径可以引入其他wxss
文件。这里的样式可以被实际页面的样式所覆盖。config.js
:这个可能不是官方标准的文件,因为文档里没有提及。这里默认只是放一些全局配置信息如服务器地址,每个接口的引用地址便于在使用的位置使用require('../../config')
引用。
页面配置
小程序专门定义了几种文件格式。假设这里创建一个叫做index
的页面,那么需要在index
目录下新建以下几个文件,分别是:
index.js
:即普通意义上的JS文件,其主要用于声明当前页面的结构。同这个小程序的app.js
一样需要一个Page({})
声明,里面包含公共数据声明与方法声明。index.json
:是一个标准的JSON文件,与全局app.json
一样index.wxml
:微信小程序定义的模板标记语言,使用微信给定的标签编写可视化界面。在文档中首先介绍的数据绑定,页面渲染也都体现在这里。index.wxss
:单个页面的样式文件,主要针对index.wxml
使用,可覆盖全局app.wxss
文件。
值得注意的是这几个文件是自动关联的,并不需要收到配置,所以请保持命名的一致性。
如上图即index页面的代码片段,这做简单的解释。bindtap
属性类似于@click
用于调用index.js
中的login: function(){}
。图片中src
属性使用{{}}
胡子语法用于声明这其中是JS代码段,常用于变量输出和多目运算。而其中的wx:if
属性为条件渲染,即满足if
条件才渲染此标签。同样的还有wx:elif
和wx:else
。
wx:if
与wx:hidden
:if是不满足条件根本就不渲染,hidden是已经渲染但是是否处于hidden状态而已。
1.2 例子
说了那么多不如来点例子实际一点,为了UI的便捷这里使用微信官方的weui
样式库。小程序的控件样式样例我相信不少朋友都看过,那个就是使用weui
编写的。其本身实现了几个模板控件,更为重要的是它提供了微信官方的样式表,我们只需要按照自己的想法写标签,再引用这套样式即可。
也许是第三方组件已经非常完善的缘故,
weui
这个项目已经很久没更新了…
接下来我们实现一个文章渲染界面,算是比较有代表性的。文章排版是一项非常困难的工作,现有的方案是直接输出html显示,或者使用标记语言与markdown再使用类似模板引擎的工具渲染成可显示界面。在微信小程序端我觉得首选不够优雅,再者这效率实在是堪忧。于是我定义如下数据结构。
1 | { |
首先需要声明的是如果设计出一个兼容普遍意义上网页格式协议的话其实是非常困难的,比如难以处理的多级标题,各类图文混排等。我这里借用markdown的思想将文章格式固定下来,即文章分为若干结构(sections)
,每个结构内只有一级标题(title)
,这个标题下最多只有一个题图(image)
,但是其下段落就有很多(paragraphs)
,如块(block)
,普通分段(p)
,加粗(bold)
。另外当前协议不支持混排。既然是文章渲染那么这个页面就命名为article
。
1) 首选在全局配置文件app.json
中配置路由
1 | { |
2) 在列表页面配置跳转导航
1 | <view wx:key="article-list" wx:for="{{dataSource}}" wx:for-index="index" wx:for-item="item" |
如上述代码使用<navigator></navigator>
标签设置导航,导航地址url
使用相对路径并使用类似于http url传值的方式传入一个id={{id}}
值给article
页面。
3) 在article.js
文件中接受传入的文章ID并向服务器发送请求
1 | //article.js |
在生命周期方法onLoad
中获得参数options.id
,使用this.setData({ articleId: options.id })
将此JSON对象合并入Page({})
中声明的data
对象。注意修改data:{}
的值都要是有this.setData({})
,并且这是合并对象而非覆盖对象,即没有合并的属性依旧存在。
随后调用loadData
方法把articleId
拼接到url后面向服务器发送get
请求,再将服务器返回的数据写入dataSource
对象。
4) 页面渲染
1 | ... |
这个列表渲染可以说的东西还挺多,算是比较有代表性的。
wx:key
:为元素指定一个唯一ID,特别是在列表渲染中设置key值会大大提高效率。理论上这个值应该是整个页面唯一,但是微信小程序似乎没有做这方面验证,不过为了出现不必要问题,还是请尽量保持在页面的id值唯一。wx:if
:条件渲染,如果if条件不满足则不渲染整个UI节点。这里的意思是存在episodes
这个JSON节点再进行渲染,如果这个数值为空也不渲染则还要加上episodes.length > 0
判断。wx:for
:数值循环标签,要配合wx:for-index
和wx:for-item
使用,相当于重命名一个索引值和item值。遗憾的是不能使用wx:for={{(item, index) in episodes}}
这样的语法,多写两个属性显得比较繁琐。可以看出wx:for
是列表渲染的关键。- 数据绑定:数据绑定算是最为重要也是最为灵活的地方了。简答来说
{{}}
用于向页面输出Page({data:{}})
中的data数据,但是{{}}
本身表示一段代码,所以可发挥的空间就非常大。值得注意的是标签中的{{}}
更多的是输出,而属性中的{{}}
更多是输入。在输出部分主要用于变量输出与拼接输出,当然这里也包括wx:key
这类。而输入部分更多是为了运算,这主要指列表和模板。 - 样式绑定:样式动态绑定属于比较常用的功能,即动态切换css样式,如动态绑定class。如上代码中的文章段落部分
weui-article__p
,这里包括普通段落,加粗段落和块段落。通过判断paragraph.type
的值动态为view
标签增加block-quote
样式或者block-bold
样式。 - 方法绑定:对于方法的绑定仅限于事件绑定,如
bindtap
。但是你可能想在样式绑定那里如果一个判断比较长,那我能不能把这个过程写在方法里,并使用{{}}
输出方法的return
呢?非常遗憾至少目前还不行。 block
:标签为单纯的布局标签,本身并没有显示元素。如果仅仅是做条件渲染又不想再包裹一层,则是不错的选择。
如上图的预览效果,这里分辨有普通段落,块段落(类似markdown的尖括号)和加粗段落。
1.3 Vue.js ?
在看了微信官方的开发者文档之后,再加上weui
这样的样式框架我们基本上能做出一个像模像样的小程序。简单来说这其中主要分为UI部分与微信API部分,API部分基本是标准的JS没有多少定制。反倒是UI部分有相当多的限制,初看之下似乎与传统的前端开发完全没有关系。那么我们是否为了小程序的开发完全独立出一个项目呢,额外维护这么一个技术上不相干其而无法重用的项目成本是相当高的。那么现实究竟是不是这样呢?
先不考虑UI层的展示与标签,我想有过前端经验的朋友会感觉到,这怎么隐隐约约有Vue.js
的影子。
上图为一个Vue
可重用组件一般以xxx.vue命名,使用时在另外一个组件文件中直接引用即可。而小程序单个页面的几个文件俨然就是这个文件拆分开来。而其他的事件、数据绑定、条件渲染也有非常相似的地方,更为关键的是vue生态本身有很多非常高级的功能,是国内前端的主流技术,有大量的扩展和第三方库可以使用。
那么能否将以往的PC端或移动端前端通过某种方式转换成小程序呢?能否重用以往的UI设计,以及相对复杂的业务代码呢?
答案是肯定的,那么就请忘掉上面微信小程序官方给我们的各种条条框框,重新开始吧。对重新入门。
2. 重新入门
不知道大家对现在的前端是何看法,不知道大家是否用过主流的前端框架,同时对于各位大牛以及大厂时不时推出自己的框架有何想法。自从V8
与node.js
推出,前端基本没有本质的技术发展。即便每天都有新框架甚至新的语言诞生,它们都不是为了进行技术革新解决某项无法解决的问题,它们目标仅仅是为了提高我们的工作与生产效率。
2.1 前端框架?
jquery react vue组合图
前端框架简单的可以分为两类,即纯UI框架如Bootstrap
、Foundation
、Semantic UI
、UIkit
,或者综合脚手架类如React
、vue
、AngularJS
还有大量的衍生框架。如vue
衍生出的饿了吗开源的ElementUI
,react
衍生出蚂蚁金服开源的AntDesign
等。
但是需要说明的是当我们将框架的概念泛用的今天,请务必真正的明白究竟什么是框架,什么是库。其实Bootstrap
、jQuery
、vue.js
这类本质是一个供我们使用的库,而AngularJS
这种规模才能称之为框架。因为AngularJS
已经考虑到了方方面面,是一个大而全的方案。
类库:我调用你。框架:你调用我。
前端工具组合图
前端框架之所以可以大放光彩离不开V8
和node.js
,以及在node.js
上发展起来的各类工具。各种第三方类库与扩展以在npm
的管理下极其方便的被集成到项目中,并在webpack
、Grunt
、Browserify
等工具的配合下使得我们仅仅关注ui的展示与业务的实现。一下子我们可以不用管考虑类库的版本兼容,浏览器的的差异,ES5与ES6,我们只需要按我们的想法使用最新的规范,写出最漂亮的代码,其它都让工具去考虑吧。
2.2 UI 组件
现在我们重新回到小程序,我们知道UI层的官方规范weui
已经很久没有更新了。用过的朋友也可能觉得需要改进的地方很多,那么是否有替代方案呢?
1) ZanUI-WeApp
微信小程序官方只是给出了最基本的文档,这些文档对于企业开发者来说肯定是无法满足需求的。企业需求多种多样并且无论是UI还是业务都有很高的复杂性,同时由于需要长期迭代开发必须有比较完善的规范与代码重用。
在我印象中有赞团队开源的小程序UI组件库ZanUI-WeApp
,是第一批此类开源组件,并且有赞很早就与微信官方合作替我们解决了很多问题。同时有赞团队也做商城平台的运营工作,方便第三方通过其自建微信小程序商场的方式上线自己的小程序商城。
2) iView Weapp
iVew
是最近出现的小程序UI组件库,实际体验过小程序demo后给我印象非常深。无论是加载速度还是UI切换都非常流畅,并且相应的提供非常丰富的组件可供我们使用。并且看了不少开发者的留言都对其有相当高的评价,所以我在这也是非常推荐这个小程序UI组件库的。
2.3 小程序开发框架
既然前端开发有这么多资源和工具,那么我们能否直接或间接的使用前端这么多年的资源和经验的?答案是肯定的。
1) WePY
微信官方开源了一款叫做WePY
的小程序组件化开发框架,其主要看点是类似Vue.js
的风格,可使用npm
支持ES5+等。仅看到这些我想很多开发者都心动了吧。
1 | <!-- Demo --> |
看这官方的Demo是不是有一种写Vue
组件的即视感?非常重要的一点是我们摆脱了小程序开发这个独特又陌生的环境,又看到了我们熟悉的npm
。虽然相对小程序开发这种隔离感有一定的缓解,但是这类似Vue
的风格毕竟还不是Vue
我们并不能进行愉快的代码重用,于是新的框架诞生了。
2) mpvue
mpvue: Vue.js in mini program。
美团开源的这款完全基于Vue.js
的小程序开发框架,修改了Vue.js
的runtime
和compiler
进而是其可以在小程序环境中运行,同时又给予我们使用Vue.js
的开发体验。
2.4 DSL
DSL(Domain Specific Language)是一种用来解决特定领域问题的计算机编程语言
这里多说一下DSL,很多人其实是因为JS才第一次认识到DSL。如果说ES6到ES5的转换大家很容易理解,那么为什么TypeScript
和CoffeeScript
这种并没有遵循ES规范的语言可以运行在ES环境?其实开发者写什么语言遵循什么规范并不重要,重要的是最终经过解析和编译之后是什么语言。
在经过Compiling(编译)和Transpiling(转译)之后这种语言能够转换成另一种可运行语言就可以了,而另外一种语言可以是高级语言甚至可以是机器语言。就好像JS和Java互相转换这种看起来不可思议的过程,其实仔细想想并没有什么不能理解的地方。
所以回到微信小程序我们就不难理解,为什么我们可以使用Vue.js
开发微信小程序。因为开发者的开发过程和程序的运行过程本来就没有必然联系,你使用Vue.js
开发在经过编译后已经被转换成微信小程序运行环境可识别的语言了。所以理论上我们可以使用任何有助于提高我们工作效率的语言和工具做开发,只是我们必须要有编译与转换工具。
2.5 工具
如果你注意过微信小程序的官方开发工具,你会不会觉得它像是一个Chrome?再进一步说它是不是基于electron
?
所以是否依靠各种开源工具能够重建一个定制化更强的微信开发者工具?其实这当然是可以的,但是到目前为止真的不推荐。在微信小程序发布之初其开发者工具非常简陋,并且限制非常多,所以那时候真的有不少堪称黑科技的第三方工具如wept
。但是这几年微信小程序有了突飞猛进的发展,各种配套工具也日渐完善,这时候真的没有必要再开发一个定制化的微信小程序开发者工具,因为仅仅是兼容性就有巨大的工作要做。
我们虽然没有必要再造一个小程序开发者工具,但是可以制作一些辅助开发插件也未尝不可。当然这些就是后话了。
五、最后
在小程序审核的期间写了这篇文章,其实很大部分是对前端开发的怨念。前后端分离的思想也才出现没有多久,这导致了很多公司前端的声音比较小。但是事实是由于业务的发展和对用户体验的追求,前端的复杂度已经越来越高。在后端依旧使用不知变通的设计思想与开发步骤进行设计的时候,前端不得不将本该属于后端的功能在前端再实现一遍。虽然V8
的性能越来越强,但是随着复杂度的上升,前端集成的各类框架越来越复杂,导致webpack
已不堪重负。随着每次npm run build
的时间越来越长,机器的发热量直逼android
和iOS
app的编译,甚至传说还出现过内存不足导致编译失败的情况…
诚然现在前端发展过快导致前端开发人员水平参差不齐,颇有移动端android
泡沫兴起的感觉。不少后端同学指责前端不考虑性能问题过于急功近利,但是后端同学也并没有为前端的API接口做过多的易用性方面的考量。随着微信小程序的飞速发展也许这种情况能改善也说不定,这点我非常的期待。
等这个小程序上架之后再贴出二维码地址,在这个入门小程序的基础上将来会有更为有针对性的小程序开发指南,敬请期待。