07年做的小程序出了一点问题,主要是播放接口变了。(像这种API接口突变,而且拒不兼容之前调用方式的行为真是很恶心。)
把之前尘封的项目从git上拉下来,项目使用的脚手架都比较老了,很多依赖都[deprecated]了。
正好最近很忙,那就重构一下吧。
脚手架选择
目前小程序开发的有以下三个框架:
这三个框架中前两个是基于vue.js的,第三个是基于react的,react在阿里实习的时候用过一段时间,忘得差不多了,所以主要是前两个的对比。
简单来说,mpvue和通常的vue项目写法差别不大,主要是template + script + style的方式构建组件,然后框架把code parse成符合小程序的代码风格,状态管理可以使用vuex;wepy是腾讯推出的一款框架,结合了vue.js和原生小程序的相关语法,在其中加强了事件、异步这些特性,而且文档比较全一些。
综合比较两者之后,我选择了mpvue文档来作为开发框架。
ui风格
由于是我单方面想重构,并没有拉上之前的前端,(ps:他应该现在在airbnb呆的很爽吧。。。)所以我需要一套基础的布局样式,这里选择了一个色彩对比度比较高的colorui。
全局引用,小程序中所有padding、text-size、margin这些基本都是用一套风格,保证了统一的视觉效果。
一些特殊的组件需要还是需要手动编写css的,这块比较费劲,因为有的时候比较喜欢精确地显示效果,花费了比较多的时间在这块。
后端
我们的业务web使用Laravel构建的,api这里和业务系统使用一套同系列的软件Lumen,这样数据格式交互比较方便一些。
另外对于这种接口编写真心觉得PHP就是最后的语言,返回一个json接口直接:1
2
3return [
'key' => 'value'
]
就行了,然后访问接口就行了,所见即所得,语言层面的差异真心不是靠benchmark节约几毫秒就怎样,还是看能够快速实现,在服务得到验证之后可以针对进行各种优化。
小程序的一些细节
网络请求
网络部分使用fly.js封装实现,然后挂到了Vue.prototype.$api下,这样在所有组件中都能访问,fly.js中可以设置全局拦截器方便了性能检测和业务的拦截,比较方便。
关于全局数据是否有必要使用vuex
全局数据类型有人说可以之间定义全局变量,但是这些全局变量无法实现响应式,比如用户登录成功之后页面刷新,购买的价格从非会员间变为会员价,这些都依赖于登录状态的变化而响应式更新。所以这块我才用的是store.js + computed计算属性完成的。更改数据也很简洁,使用commit就可以了。
屏幕尺寸
小程序一个比较麻烦的点是运行的手机平台多,各种屏幕尺寸、分辨率不同,这时就要求页面的样式需要具有伸缩性。
通常使用iphone6的标准尺寸进行布局就可以,此时1px = 2rpx这块的换算,mpvue会帮忙做,比较贴心。
建议在程序启动的时候获取一些必要的显示参数:1
2
3
4
5
6
7
8
9wx.getSystemInfo({
success: e => {
Vue.prototype.$StatusBar = e.statusBarHeight
Vue.prototype.$ScreenWidth = e.screenWidth
let custom = wx.getMenuButtonBoundingClientRect()
Vue.prototype.$Custom = custom
Vue.prototype.$CustomBar = custom.bottom + custom.top - e.statusBarHeight
}
})
这样在子组件中可以方便的获取:1
2
3
4
5
6
7data () {
return {
StatusBar: this.$StatusBar,
CustomBar: this.$CustomBar,
Custom: this.$Custom
}
}
布局方面
尽量使用flex布局,不用过多考虑各种浮动、清除、定位问题,拥抱现代化的布局方式吧。
阮一峰的flex布局教程可以多看几遍。
音乐播放组件
小程序后台音乐播放的API变成了一个单例的manager,这时候要求ui和manager做比较多的同步工作:
- 用户拖动进度条 => 进度、时间都更新(此时不再响应music的time变化,因为音乐还在播放) => 松开进度条 => seek music
- 用户点击进度条的位置 => 进度、时间都更新 => seek music
- music play => 更新时间、进度 => 更新进度条位置
这几点需要反复进行测试,确保ui和音乐播放可以双向同步的。
分享页面的进入路径
小程序存在多个页面,用户都可以选择分享出去。只需要在page中设置onShareAppMessage方法就行。
如果其他用户从分享的页面直接进入小程序,小程序的page stack中只有这一个页面,此时造成wx.NavigateBack()函数失效,新来的用户无法到达首页。
这个问题我想的办法是进行首页转发。
- 页面跳转是可以携带参数的,如果用户进入的是二级页面,则二级页面首先进行
reLaunch到首页,并携带redirect参数标明二级页面位置(还可以包含其他数据,比如商品id等)。 - 首页onLoad之后,获取到
redirect参数,拼接url,然后进行navgateTo跳转即可。
这种方法可以重建page stack,这样新的用户可以通过返回方式进入首页。
后端接口遇到到的一些小问题
下单金额少一分?
PHP精度问题,微信支付要求以【分】为结算单位,如果使用了【元】小数 * 100计算,此时结果可能不足,比如¥19.9,结算成1989分:1
$price_percent = (int)($price * 100); // wrong
这个问题主要是PHP的浮点数保存精度造成的。
比较推荐的办法是使用PHP的高精度算法:1
$price=(int)bcmul(110, 100);
退款证书问题
上线测试的时候买了很多东西,测试完之后要退款结果证书又过期了,现在微信支付采用了新的顶级CA颁发的证书,重新下一遍,两个pem文件加到服务器上,此时curl又太久了,因为存在一个历史bug,此时又去升级curl。我用的是第三方的yum源才能更新CentOS7上面的curl。
成功退款了。
反思
一般涉及到工具使用、框架使用、编程语言的tips我比较少写总结,我觉得这些东西变得很快,框架日新月异、技术更新迭代、新的特性简化代码……但是大部分人的大部分时间又花在这方面,确实经常做这部分工作会使人变得很熟练,但也就少了很多解决问题的时间。
我恰恰觉得解决问题的时间才是项目中比较有意思的点,并不是主要因为解决了问题推进了项目进展,而是通过解决具体问题,我们的确定问题所在、寻找可能的解决办法、解决问题这种路径会不断地优化。
所以解决一个具体的问题不是能力的体现,如何形成并优化自己解决未知问题的模式才是能力的体现。
访问看看
