小程序爬坑日记
最近因公司安排首次接触了微信小程序的开发,本来仗着有Vue的基础以为很简单,没想到开发过程中还是遇到了很多坑,不过只是接触了一个小程序的案例,好多官方api接口还没有使用过,以后有了新坑再补上。
注意本文默认你已经掌握了小程序的基本开发知识或者研读过小程序的官方文档
整体框架
配置
小程序的官方文档,介绍了整体框架的设置,里面的配置都是在.json文件中实现的。大致配置官方文档里都有详细的说明,多说一句navigationBarTitleText
如果你希望一个page复用,并且名字不一样的时候,最好在app.json里面把这项置为空字符串,然后再具体页面通过wx.setNavigationBarTitle
动态修改,不然会有一个跳动的感觉。在使用enablePullDownRefresh
的时候,建议把backgroundTextStyle
的值写为dark
,是一个符合大众口味的样式。
路由
小程序的页面维护在一个最大长度为5的堆栈中,创建新的页面会执行对应页面的onLoad函数并且压入到栈中,返回已存在的函数只会执行onShow函数。这个规则可能会影响到我们想自定义路由跳转的设计,所以在设计页面跳转时候,要考虑栈的前后。另外,关于路由跳转,建议使用js代码实现,这样可以判断是否跳转以及跳转到何处,如果固定连接可以使用navigate
标签
页面间传值
各个页面间传递数据也是经常出现的场景,不过小程序在这块的支持也不是很好,可以通过如下代码进行简单的query传值
wx.navigateTo({
url: '/pages/index/index?key='+value,
})
但是如果传递对象就有些困难了,此处的解决方案有两个,一是放到app.globalData中,二是放到storage中:wx.setStorageSync('key',JSON.stringify(objectValue))
运行机制
- 小程序没有重启的概念
- 当小程序进入后台,客户端会维持一段时间的运行状态,超过一定时间后(目前是5分钟)会被微信主动销毁
- 置顶的小程序不会被微信主动销毁
- 当收到系统内存告警也会进行小程序的销毁
运行机制在小程序的官方文档中有介绍,不过由于位置不显眼,所以单独在这贴一下,至于如何维护小程序的运行机制以及用户从后台回到小程序任意页面后期望的反应,需要在实践中尝试了。
表现方面
px,pt和rpx
rpx是小程序独有的单位长度,在我理解中是和rem一样的东西,因为它们都会根据设备视口的实际大小调整真实的长度。那么前端拿到设计稿后是如何换算的呢。目前看来1pt=1rpx
,1px=2rpx
是合适的方案。
组件的使用
一开始打开小程序的官方文档,发现很多封装好的组件很开心,感觉省了好多事,在实践后才发现,小程序很多组件都不能用,一用就出事,
所以在做小程序开发时候,尽量避免使用很多奇怪的组件(包括text)。不过在项目开发过程中,总是有些需求要迎坑而踩的。大概描述下本人实践过程中的痛点。
text
针对text我只想说:能用view就别用text。text可以类比html中的span
标签,但是很奇怪的一点是,text中竟然还包着一个span标签,虽然大部分样式是可以继承的,但是总有点别扭的感觉,让你觉得不可以完全把控它,所以能用view还是用view吧。
input
input和textarea都属于有用户输入交互的组件,在vue.js中针对表单组件,是有v-modal="value"双向数据绑定机制的(虽然也是语法糖),在小程序中是需要通过data="{{value}}" bindinput="{{getValue}}"
实现双向数据绑定的,再加上小程序渲染页面需要显式调用setData
方法,所以导致了输入表单组件的数据更新不及时,在用户使用时具体就体现在,用户快速增加/删除文字时会有回退的效果。
textarea
textarea还得单独说一下,因为它实在是太坑了!和text一样,textarea里面也封装了一个其他的区块,并且你无法操作它,只能改变他的父级textarea,这种情况就导致了它很难和其他组件实现水平对齐;在还不算完,textarea还拥有最高的层级(z-index = ∞),所以你即使加了蒙层的话,他还是会比你的蒙层高,这在手机端的体验是很不好的。所以目前大的互联网公司小程序textarea的解决方案是,把它放到一个单独的页面上去,避免上面提到的两种情况的发生。
scroll-view,swiper
两个都是可滚动的容器,其中swiper是类似轮播图似的容器,支持横向和纵向滚动两种模式,具体可查看官方文档,scroll-view则是一个滚动的容器,一般的滚动效果可用直接用view实现,如果真的需要用到scroll-view的话,必须要注意一点,那就是一定要给scroll-view一个确定的高度/宽度,上面提到小程序的长度单位是rpx,而此处scroll-view需要的长度单位是px,这就很尴尬了。好在小程序api有个getSystemInfo接口,希望可以帮到你。
button
其实button组件还是没什么坑的,注意下button有默认的disabled样式就可以了,可以在app.wsxx全局样式表中设置button[disabled]{...}
,修改button的默认样式
API
小程序官方api大部分是wx.api(object)的格式,其中入参object中一般包含3个回调函数,分别是success,fail,complete
promise
虽然小程序自己支持了promise,但是真机使用时发现,ios8版本是无效的,所以需要引入一个promise.min的支持库,并且实例化对象,开发过程中发现require不起作用,建议用import方式引入。
request
作为小程序最最重要的一个api,request使用起来没有什么难度。看过官方文档的例子后就可以上手使用了,需要注意的是,小程序最多允许并发5个request请求,而且request在实际使用过程中,都会被封装一层,以便完成一些希望统一处理的情况。
Storage
和webStorage一样,微信小程序的Storage是永久保存在本地的一个数据,并不会被会话结束所影响。同时Storage有两种使用方法,一种是异步的wx.setStorage({key,value,callBackFn})
wx.getStorage({key,callBackFn})
,一种是同步的wx.setStorage(key,value)
wx.getStorage(key)
。个人感觉同步方法使用的多一点,毕竟数据得不到对于后续操作应该会有影响的。另外storage还有两个不常用的操作:wx.removeStorage()
wx.clearStorage()
,可在官方文档中找到代码例子。
getLocation、chooseLocation、openLocation
获取用户的地理位置信息,使用户选择地理位置信息也是经常出现的场景。其中getLocation和ChooseLocation会申请用户位置信息的授权,如果用户拒绝后,以后每次调用这两个接口都会自动执行fail的callback,所以需要在这个回调里写引导用户重新授权的逻辑。
fail() {
wx.getSetting({
success: (res1) => {
console.log(res1)
if (!res1.authSetting['scope.userLocation']) {
wx.openSetting({
success: (res2) => {
wx.chooseLocation({
success: function (res3) {
}
})
}
})
}
}
})
}
openLocation这个接口是提供一组经纬度,然后调用地图打开并显示该地址,此处注意目前这个接口支持的经纬度格式是gcj02
不懂这个格式也没关系,只要看看官方文档的例子就知道传什么类型的值了,不过对于js这种弱类型语言,你的经纬度很可能会转换成string类型的,并且你在模拟器上看不出任何差别,不过在手机上,openLocation接口如果接受了string类型的经纬度可能会引起不工作的情况,所以保险起见,要手动转一下类型:
wx.openLocation({
latitude: parseFloat(latitude),
longitude: parseFloat(longitude),
scale: 14
})
getSystemInfo
获取系统信息可以获取到手机的各个详细信息,官方文档有详细说明此处不在赘述,只是提一个使用到的场景:通过这个接口获取到视口高度从而进行计算。一般会在scroll-view中用到。
showToast、showModal、showLoading
这三个接口都是用户交互反馈的手段,toast是一个不需要用户点击的提示;modal是一个需要用户点击的对话框,有确认和可选的取消按钮,其中按钮的文字也可以修改;loading是一个不可穿透的图标,告知用户后台逻辑正在计算,一般应用在request等待回文的过程中,注意loding需要手动关闭,所以hideLoading放到complete中比较稳妥。
toast中的文字可能会有省略成...的情况,所以在设计提示文案时要考虑字数,原生支持两种图标,如果需要自定义自己切图就可以了。
wx.showToast({
title: message,
image: '/images/icon.png',
mask: false,
duration: 1500
})
login、getUserInfo
login和getUserInfo可以使小程序获取到微信用户的基本信息,对于分析用户数据有很重要的作用。其中getUserInfo是需要用户授权的。
关于模版
前端组件化开发的思想越来越重要,模板正是小程序组件化开发的体现,但是目前这个模板机制还不是很好,比如我们可以在template里面定义结构和样式,但是其中触发的事件还是得写到引用模板的js中,解决方案是可以在js中引入公共的模块实现。
结尾的话
小程序的开发过程可谓是痛苦并学习着,作为被Vuejs惯坏了的前端,写小程序有很多不方便的地方,但是仅仅一个项目并不能用到小程序的所有特性,还有很多接口没有尝试。以后计划打算使用socket进行通讯,尝试一下用户的图片和录音功能,尝试小程序的动画接口,尝试小程序的获取元素信息接口以便开发适应各个屏幕的结构。努力努力再努力!
如有地方不明白可联系我的邮箱:[email protected]