关于本次分享
2018年9月入职丁香园之后开始接触到小程序开发,主要工作是迭代小程序项目,将过程中的收获与心得分享给大家,相比围绕着某一个细节展开来说,更多的是给大家展示个人的思路。
章节
- 小程序框架
- 应对需求
- 开发建议
小程序框架
作为一名“现代”前端工程师,大家至少会对一款“现代前端框架”框架比较熟悉,比如 Vue 或者 React,就个人而言,在 Vue 2.x 的实践相对更多一些,凭借着对一款“现代前端框架”的熟练使用,如何快速上手小程序项目?
提供我个人的一个思路,理论上可以应用到任何一套“现代前端框架”上,以官方的小程序框架举例:
首先将一个 Vue 项目中的最基础同时也是最关键的技术细节列举出来:
Vue 包含非常多的细节,我认为图上列举到的这些是其核心,掌握核心技术足够应对大部分业务场景,可以快速进行页面开发。
通过一个类比的思路,带着问题去小程序官方文档或者现有项目中寻找答案,我们来看一看使用官方小程序框架如何实现这些技术细节:
很明显这比按照顺序过小程序官方文档要快的多,效果也更棒。
当然小程序还有非常多的特性与限制,是这个导图上没有提到的,需要在后续开发过程中慢慢积累,这里讨论的仅仅是如何快速上手小程序项目。
应对需求
刚上手完成,需求就来了:
此次需求根据真实事件改编
点击“我要购买”,向服务端发送请求,待响应成功之后,跳转下一个页面,且需要收集 formid 用于下发 模板消息(模板消息可以理解为给用户的消息推送,需要在小程序中收集 formid),我们只看这个按钮的实现。
很好,看起来不是很复杂,这只是一个普通的按钮,我们做需求是有套路的,将其拆解为技术细节逐个击破:
- 布局
能直接用的东西绝对不自己写,是否有现成的组件可以拿来用呢?赶紧在咱们小程序里找一找,看看有没有长这样的组件,不出所料,找到了 A 同学开发的组件buttonA
,但是没有组件文档,还得照着组件源码看怎么使用的,引用过来样式直接ok,这是个顺利的开头! - 请求
模仿项目中之前的请求写一遍即可,很快请求就跑通了。 - formid收集
模仿现有实现写一遍即可,很快找到了一处例子,一点小麻烦,不过功能实现万事大吉!
so eazy!很快咱们的需求就做完了,自信提交 MR,进入 code-review 环节,这么简单的代码能出个啥问题?但结果却是一大波 diss 来袭:
- 经验丰富的 B 同学的 diss 道:“iPhoneX 适配做了吗?”
- 喜欢造轮子的 C 同学 diss 道:“buttonA这个组件太老了,现在项目里都改用buttonC了,自带 iphoneX 适配,formid 收集也封装了组件,直接使用即可”
- 严谨的 D 同学:“请求失败的 catch 分支怎么仅仅是给 log 出来了呢?”
在我们将代码几乎重写一遍解决了一大波 diss 之后,QA 很快就反馈了问题,你这个按钮快速点击多次页面会跳转多次。
一个看似简单的需求,过程中暴露出了很多的问题,来给问题梳理一下:
- 个人开发经验不足/考虑不够周全
- iphoneX 适配
- 没有做按钮防止重复点击
- 项目的问题
- 旧轮子满足不了需求的时候(样式改动或者加入新元素),有些同学没有选择去优化老轮子,直接造新轮子,越造越多,且没有项目文档说明,时间久了没人知道这么多轮子哪里来的,哪些能用
- 针对某些场景有些同学封装了一些组件/工具函数,由于没有项目文档说明,其他同学不知道有这些轮子,又照着较老的逻辑重新实现了一遍;或者知道有轮子可以用,但使用起来还得看看源码,需要有一定的熟悉成本
于是咱们有了《小程序开发指南》,一定程度上解决了暴露出的这些问题:将零散的技术细节封装成模块,设计原则高内聚低耦合,使用更便捷,维护性更好,并配有详细的文档帮助项目开发者快速上手,咱们来看看这些实现的变化:
- formid 收集
小程序开发指南-formId收集与上报
之前:
<view class="container">
...
<!-- 其余模板省略 -->
<form class="form-report"
bindsubmit="navAndReportFormId">
<button form-type="submit"></button>
</form>
</view>
.container {
position: relative;
}
.form-report {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
}
.form-report button{
width: 100%;
height: 100%;
background-color: transparent;
}
navAndReportFormId() {
// 其余逻辑省略
const { detail: { formId } } = e;
app.reportFormId(formId)
}
之后:
将业务无关的结构、样式、行为封装到了组件中,使用起来仅需引入,跟一个 <view>
标签一样。
{
"usingComponents": {
"formid-report": "/components/common/formid-report/index"
}
}
<formid-report bind:on-tap="handleTap">
...
<!-- 其余模板省略 -->
</formid-report>
- 防止重复点击
小程序开发指南-防止重复点击
之前:
需要在多处维护一个用于标记按钮是否可以点击的变量。
createDrugOrder() {
// 防止重复点击控制
if (this.hasClickPay) {
return;
}
this.hasClickPay = true;
return app.request({
...
})
.then(() => {...})
.catch(() => {...})
.then(() => {
this.hasClickPay = false;
})
}
之后:
将控制按钮可否点击的逻辑抽离出来,在高阶函数中进行控制,引入高阶函数包装目标函数即可,要求包装的函数返回一个 Promise
。
createDrugOrder: avoidRecall(function() {
// 业务逻辑
...
})
- 错误处理
对于可能会出错的代码逻辑,一定要把成功和错误逻辑都考虑到,成功/错误分支都要有逻辑可走,提供给用户可操作的路径,保证程序的健壮性。
小结
需求迭代过程中,将需求拆分为技术细节,参照团队共识的“最佳实践”来粘贴复制,开发越来越高效,同时对更多的技术细节进行封装,沉淀出更多数量的实践,对已有的实践不断优化,追求“最佳实践”。
开发建议
官方的小程序性能优化工具
微信官方提供了像 LightHouse 类似的评分工具,可以参照其中的建议来优化小程序。
在小程序上实现图表
很重要的一点,常用真机看效果!!!IOS/安卓都要看。
关注小程序的升级与社区动态
小程序官方在不断推出新特性完善框架,也在不断修复遗留bug,虽然给开发者的感觉是问题解决的速度比较慢。。。。。。
特别是音频,视频,canvas绘制等等会有各种各样难以理解的bug。
可以到 开发者社区 寻找答案。
回顾
- 技术细节的拆分
- 框架
- 需求
- 合理的模块封装
- 常用真机看效果
- 遇到难以解释的问题去社区寻找答案
- 被某个问题卡的时间过长及时向有经验的同学求助