本博客已停止维护,仅供浏览存档内容。了解详情 »

微信小程序初体验

在一年多前微信刚刚推出小程序的时候我是很感兴趣的,早早下载了它的开发工具来研究,可是后来发现微信却不允许个人开发者自己发布小程序,我的开发计划便不了了之了。

直到今年,微信总算是对个人开发者开放了小程序的部分功能,虽然有着诸多限制,但总算允许以个人名义发布了,于是我开始给自己开发一个小程序版的博客。

目前这个小程序已经发布,用微信扫一扫上图里圆形的小程序码即可在小程序里查看这篇文章。如果你正在手机上查看,可以将上图保存到相册,然后在微信的扫描二维码处点击从相册选择图片。

小程序主要是用 JS 配合微信自己的 WXML 和 WXSS(本质上就是 HTML 和 CSS)来开发,对于有着 Web 前端开发经验的我来说很容易上手。不同之处在于这里不能直接操作 DOM,也不能用 jQuery 之类熟悉的框架,而是用上了类似 React 和 Vue 的 MVVM 架构模式。最近几年 Web 前端领域日新月异,我却将重点转移到了 iOS 端开发,恰好错过了使用这类新架构的机会,这次借机学习一下新东西,就当是重新入门前端开发了,嘿嘿。

我的博客是基于 WordPress 的,只要对自带的 RESTful API 稍加调整即可使用,所以服务器端基本没有多少开发工作。小程序客户端方面,需要实现的是个人简介、文章列表、正文、评论和留言板等界面。

文章列表页

先从用来展示最新文章列表的首页开始,这个页面比较简单,从服务器获取 JSON 格式的文章列表数据,然后遍历显示标题、摘要和图片即可,再给每个条目都绑定点击事件,点击之后携带文章 ID 跳转到正文页。小程序页面间是通过类似于 HTTP GET 的方式传值的,需要手动把参数拼接到 URL,一点也不优雅。

正文页

正文页传输过来参数会自动被小程序封装到一个 options 对象里,从这里读取到文章 ID 之后就可以将它发送到服务器接口请求文章数据了。不过 WordPress 的文章正文是 HTML 格式的,而微信小程序并不支持原生 HTML 标签,因此无法直接显示内容。还好,经过一番搜寻,找到了 wxParse 这个可以将简单的 HTML 转换为 WXML 的框架,它会通过 JS 匹配所有的 HTML 节点,然后将它们转换成 JS 对象,再用一个非常复杂的 template 模板把内容渲染出来。虽然绕了一个大弯子,不过正文页总算是实现了。

评论页 / 留言板

这是相对来说逻辑最复杂、开发工作量最大的一个界面。嗯,其实逻辑本身并没有多复杂,工作量也不应该这么大,毕竟我的博客网页版就是用 JS 异步获取评论的,理论上逻辑都差不多,搞不好还能复用一部分代码……

开发微信小程序的时候,写着熟悉的 JS 和 CSS,用着 Chrome 的调试器(虽然只是个阉割版),恍惚间总会觉得自己正在轻松自如地做网页,然后时不时就会被现实啪啪两下耳光扇清醒。

刚开始制作评论页面时还挺顺利的,获取从上一个页面传进来的文章 ID,然后从服务器端接口获取文章列表,页面滚动到底部时自动载入更多等等都很容易实现。样式方面确实复用了网页版的许多 CSS 样式,所以开发起来还算轻松,全然不知一只脚已经踩进了大坑。

当我准备处理回复评论显示的时候才发现,微信小程序竟然不能递归嵌套 DOM 元素!WordPress 的评论嵌套是子评论中保存父评论的 ID 字段来实现的,在绝大多数编程语言中,只需写个简单的递归即可实现类似下面这样的树状结构:

这样即可将相关的评论都显示在一起,方便“盖楼”回复。可是 WXML 的 DOM 元素必须静态写好,除了 for 循环之外似乎并不能在 runtime 动态添加节点,然而 for 循环只能用来生成单层结构,不能嵌套;我试过用 template 嵌套自身来实现递归,失败;用 template A 来嵌套 template B 可行,但 B 却不能再套回 A,失败;用 for 单层渲染,然后用 @ 的方式实现类似于微博的评论显示方式,体验太差,放弃。那就先全部渲染出来,再用 JS 把 DOM 挪到对应的父元素里?抱歉,不可以直接操作 DOM。

上网搜了一圈,吐槽这一点的开发者不少,比如 wxParse 的作者在一篇文章中提到的:

无法循环使用模版下,如何处理多级 HTML 嵌套解析?既然不能够实现完美的代码较少的方式,那我们就采用一种笨办法,手动循环出 N 个模版,因为在实际场景中,尤其是在文章的 HTML 中不会出现超过 10 级的嵌套,那么这样我们可以手动写 10 个模版,进行循环调用。

难道真的得用这么笨的方法来写?何况文章内的 HTML 嵌套或许不会超过十级,但评论盖楼就是另一回事了。不甘心,继续查找解决方案。翻遍了官方文档,看完了为数不多的开源项目,浪费了若干小时的宝贵时间,却并没有找到更好的方法。有一个同样基于 WordPress 的开源微信小程序也是用手动写死五层嵌套的方式来实现的:

这对于有代码整洁强迫症的我来说简直是无法忍受的。然而在这个问题上耗费的时间精力已经超过开发整个微信小程序(包括服务器 API 调整)的总和,我不得不妥协,在代码整洁和功能完整之间选择了一个平衡点:手动写了一层嵌套。所以现在只能看到评论的一级回复,给这个回复的再次回复在小程序里是显示不出来的。思路虽然简化了,但实际开发过程中还是有很多需要额外处理的地方,细节我就略过不表了。

相对而言,发布 / 回复评论的页面就简单多了,界面就是一个评论表单,只需获取评论者的微信昵称和头像 URL,跟着表单数据一起提交给服务器即可。本想将评论者的微信头像 URL 作为一个 commentmeta 存到 WordPress 的数据库里,没想到才出狼窝又入虎穴,又踩到了 WP REST API 的一个大坑:自带的保存评论接口不能提交 commentmeta 字段。关键是不能提交你明说也行啊,我想别的办法就好,偏偏官方文档又语焉不详,让我查了一大圈,最后一气之下自己重写了整个接口。这个经历让我更坚定了 Camarts 改版时要自己写 CMS 的想法。

再加上点赞等功能之后,评论功能总算是完成了,留言板复用了评论页面,只是稍微调整了一下界面细节使之更适合显示较长的内容。麻烦之处在于留言板的入口,我的设计是在界面底部的 Tab Bar 导航栏上,微信小程序提供了这个组件,目测是原生实现的,切换起来挺流畅;不足之处在于样式太死板,可供自定义的选项不够丰富,调整了半天依然实现不了心目中的设计,只好自己用 WXML 和 WXSS 实现了,虽然麻烦些,但可以完全自己设计,在 iOS 端还能实现半透明模糊效果,看起来漂亮多了。

个人简介页

Tab Bar 上的另一个页面是我的个人简介页。原本我打算将我个人主页(dandyweng.com)上的内容全部移植过来,但前面的折腾已经耗费了太多时间精力,我也实在是没心思继续了,于是只写了几段文字,加上进入我个人主页的按钮,草草了事。由于微信小程序不能直接跳转到网页,所以点击按钮之后只能将网址复制到手机剪贴板,还需要到浏览器地址栏粘贴才能访问。

我对文章正文内的站外链接也做了类似处理,再完善一些界面细节,本次的微信小程序就基本完成了。

小结

通过这次的开发体验,实话说,我对微信小程序总体上是偏向失望的。

诚然,小程序在网页和原生应用的结合方面做得确实不错,我开发 Vary 时也遇到过网页与原生结合的难题,深知其中不易。比如当跳转页面时,可以明显看出是通过原生方式实现的,体验远超网页的链接或 AJAX 跳转;数据和 UI 分别加载的方式大幅提高了加载速度,达到了与原生应用非常接近的用户体验,同时微信扫个二维码或者在聊天窗口里直接点击卡片就能进入小程序,免去了原生应用需要下载的麻烦;更重要的是能够一次开发即可同时投放 iOS 和 Android,虽然必须在微信里运行,但以微信的体量而言,这几乎不是问题。

那为何失望?归结起来就两个字:限制。

微信小程序本身作为一个产品,在规划时需要一定限制,这可以理解;技术层面上的复杂度太高,为了保证可用性做出限制,我也可以理解。不能接受的是人为的、毫无说服力的限制。尤其是对于个人开发者而言,小程序看似有很多功能,但实际开发时往往都是这个不能用、那个不让用。这点我在几年前开发微信公众号机器人的时候就有过类似体验,看来是微信乃至腾讯一脉相承的做法。

我承认要运营这样一个互联网产品不易,个人开发者确实更难监管,但如此草率地“一刀切”歧视所有个人开发者正是对自己的管理能力缺乏信心的表现。不恰当地反观 Apple,在开发和上架一个 iOS app 的过程中就完全感受不到个人与企业名义有任何区别。当然,除去公司之别亦有国情之别,其中微妙不言自喻。

限制二字更多体现在审核环节。对微信小程序审核之严格我早有耳闻,为了确保不触碰任何红线,我在开发前就仔细研读了官网的规范,但在开发完成提交审核时还是以各种含混不清的理由被拒绝了,比如说我的博客含有“文娱资讯”内容,必须要相关资质的企业才能发布等等,如何定义“文娱资讯”?具体哪篇文章违规了?无人告知,申诉无门。上网查了一圈才知道,大家都称之为“薛定谔的审核”,基本上是碰运气,一次过不了随便改点东西再试一次可能就过了。

这时我才知道,原来那个“规范”只是个摆设,能不能发布是审核员说了算的,然而审核员是很不靠谱的,他主观认为你行就行,说你不行就不行。而且我觉得审核员是倾向于拒绝的,因为他要是审核通过之后出了什么问题估计就得自己背锅了,因此宁可错杀一千也不放过一个。

这给了我极大的不安全感,因为自己辛辛苦苦学习、设计、开发和调试的心血之作很有可能因为某个不靠谱的审核员的一念之差而全部付诸东流。这种不安全感让我不敢、也不愿再为它付出更多的时间精力。

最终我的小程序虽然侥幸通过审核,但可能不知哪一天就会触碰到某条看不见、摸不着、说不清、道不明的规定而被强行下架。所以大家趁着现在还能用,赶紧体验吧。