在使用过程中想到一点记录一点,只是个人感想。
支付宝小程序的底层应该是
React Native
的,但是,小程序界面的语法,跟weex
更接近。比如,.axml
文件,相当于<templete>
标签;.acss
文件,相当于<style>
标签;.js
文件,相当于<script>
标签。
利用相同的文件名称这一点,将三者联系起来。提供了
TODO
和demo
两个模板,这个很不错。特别是demo
这个,可以当做手册参考,挺好的。感觉应该再提供一个单页面的空白工程模板。用熟练了之后,还是空白工程最好,不用删除了。“新建文件夹”或者“新建文件”,只有右键菜单,没有菜单选项,有点小奇怪。“新建页面”选项有点奇怪,出来一个无法辨别类型的文件。期望中,应该是出现一个文件夹,自动生成相同名字的4个文件
(.axml, .acss, .js, .json)
断点调试,保存文件后自动刷新,输入
APPID
之后可以真机预览,都是很好的功能。tabbar
在app.json
中配置,不能动态修改。这个有点限制。比如,节日期间自动改变tabbar
的文字和图标就很难实现了。.json
文件中对象成员,数组的最后一项不能带逗号,(比如app.json
)。js
文件是可以的,(比如app.js
)。不会自动保存,需要手动保存。没有保存文件菜单,右键菜单也没有,需要使用
“command + s”
菜单快捷键。对于记不住快捷键的使用者是个小麻烦。另外,这个快捷键只是保存当前文件,暂时还没有找到保存所有文件的方法。打开文件的顶部标签如果有个*
,说明没有保存,记得切过去,“command + s”
一下。编辑,回车换行的缩进,有时候感觉很傻的,跟
webstorm
还有差距。有时会出现莫名其妙的错误。将鼠标放到最前面,回退一下,可能就好了。点击的响应函数,在
Page
中可以写成普通函数的形式,也可以写成箭头函数的形式。都可以正确响应点击事件,没有this的指向问题,不需要bind
,估计是框架在js
和axml之间做了bind
。Page
中的响应函数都写成函数的形式,因为有时候要用到异步的形式,async
,这个箭头函数不支持。文件夹的名字不要命名为
api
,不然import
的时候总是报错,原因都找不到。删除文件操作尽量脱离
IDE
,否则有造成卡的风险import, Promise, async, await
等ES6
的内容都可以支持。-
代码复制过来之后,经常会出现空格导致的错误。手动删除空格,重新排一下版,基本上就可以了。
将图上那个小红色回退,删除掉,保存,不再出现就可以了
location.js
也是不允许的文件名称,可以考虑用position.js
代替import
可以是相对路径,也可以是绝对路径。绝对路径开始的/
对应工程目录,有时候还是很方便的。绝对路径,IDE会自动转换为相对路径。import
第三方库,需要先用npm安装,然后直接填名字就好,不需要带路径。node_modules
文件夹在工程的根目录下,不会再IDE
中显示。
自己管理第三方库,没有框架帮忙,稍微有点麻烦。比如,moment
这个库就能正常安装,正常使用。但是想antd-mobile
这么大的库,安装之后编译都过不了。antd-mobile
是带H5界面的,这种库不适合引入小程序中,最好是跟界面无关的工具类库。自定义分析接口现在能用了,但是管理界面配套的配置项还没放开,据说这项功能现在还没好。
音频,视频等功能还没有放开,不过内部资料还是有的,接口能用。目前只看到播放功能,录音功能还是没有的。芝麻认证,需要签约,查一下需要钱的。人脸识别,身份证识别等功能都是有的。
.gitignore
文件是没有的,内容可以从前端或者RN项目复制一份。至少下面两项可以考虑包括:
node_modules/ , .tea/
如果习惯了
WebStrom
,照样可以用的,代码编辑保存都正常进行,只用IDE
进行编译,预览,调试,真机验证。用两个工具在一份代码上工作,可以很好地取长补短。至于习惯了VSC
的,单用IDE
就差不多了,两者风格很相近啊,用两个的意义不大。app.acss
文件是可选的,个人感觉还是不要为好,让每个页面保持相互独立。
至于公共样式,可以考虑新建一个文件夹,里面放多个页面共用的样式,用有意义的名字命名。需要用到的地方,导入再用,这样意图更明显。默认是
标准盒子模型
,是纵向的。如果涉及到横向布局,比如表格的一行,可以考虑采用弹性盒子模型
,只要在容器类选择器加上display: flex;
就可以了。接口
my.httpRequest
在模拟器中可以通,在真机上会遇到“无权跨域”的问题,可以通过配置http白名单的方式解决。支付宝要退出重启,让修改生效如果是阿里集团域名,会出现“无权跨域”,又不能添加白名单的情况,提示“无法添加阿里巴巴集团域名”。解决方法是找阿里对应的人说明情况,走审批流程。
页面跳转深度不能超过5,这个限制要注意。重新加载的话,返回的内容会变。
my.reLaunch
和my.redirectTo
都可以降低页面深度。如果不是特别需要,
tabbar
就不要引入了,限制太多,不够灵活。一般情况下选择器用
Picker
组件比较好,返回的是index
。数组还是用Object的数组好,因为一方面要显示给用户看,另一方又可以传数据给后台。Picker-view
可以用于多级选择,比如三级地址选择。不过它和内容在同一层次,没有Modal
弹出效果。可以通过a:if={{show}}
的方式来控制显示与隐藏。比如点一下按钮,显示选择界面;再点一下,隐藏选择界面,更新选择内容。这是手机上比较常见的一种交互方式。
这种用法,有个限制条件,就是级数要事先确定小程序的信息正向传递还是比较方便地,也就是说,
A -》B
;A
要传信息给B
,只要挂在url
后面就可以了,中文也可以,不需要编码。B
中只要在onLoad(query)
函数中直接取就可以了,都是对象的成员,比较方便。小程序没有信息的回传机制,也就是说,
A -》B
;假如B
是信息录入页面,但是B
中的信息没有办法回传给A
。变通的方法有两个,一个是通过全局变量,另外一个是通过本地存储。在
demo
中,有个总体样式
page {
background-color: #f8f8f8;
border: 1px solid rgba(0,0,0,0);
box-sizing: border-box;
}
其中的box-sizing: border-box;
表示盒模型中,将padding
和border
都计入width、height
,这是推荐的做法
box-sizing
- 在
demo
中,经常有flex: 1;
一般用在子组件中,这个等价于
.item {flex: 1;}
.item {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
}
弹性盒模型在小程序中用得比较多,需要重点看看。
flex设置成1和auto有什么区别
- 从
H5
迁移过来的代码,比如dva+antd-mobile
布局的界面,像素单位需要将px
修改为rpx
。设计的时候,按照iPhone6
的尺寸,宽度就按照750px
来设计,应该刚好能对上。
UI设计的时候,按照iPhone6
的尺寸设计,单位是px
,实现的时候,小程序的单位用rpx
,尺寸数字是一样的。
至于1像素的分隔线,用2rpx
和1px
都是可以的,推荐用1px
单位还是建议用rpx
,在IDE
中调试时看到的是rem
,这个在不同的手机上适配比较方便。当然,尺寸会根据不同屏幕进行拉伸。
rpx(responsive pixel)可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
这段话是手册中的,不是非常理解。印象中iPhone6的宽度是375×667点,对应到UI的分辨率是750×1334 px
小程序手册样式一节
iPhone/iPad/Android UI尺寸规范
常见的
html
标签,比如div、span
都不支持,对应的应该是view、text
,又不完全一样。IDE
提示有的标签可以用,输入的时候不提示的,很可能不支持。使用了不支持的标签,结果就是红屏。form、piker、block、
等标签可以认为是不可见标签,不显示,不用放样式。当然,放样式也是可以的,作用相当于view
,可以认为是容器。纵向内容,用普通盒子模型来布局,横向的,用弹性盒子模型来布局。这是比较取巧的方式。统一用弹性盒子模型来布局也是推荐的做法。
从
demo
来看,样式采用基本的css
语法,less
的写法估计不支持。从组件的角度讲,
React
的jsx
比较方便,可以封装一些操作。这里的templete
相对就弱一些,只能是数据和显示,没有办法将JS
逻辑封装到组件中。目前还没有事件
emit
机制,比如,程序模拟用户点击就没法实现。小程序中不能跳转
H5
页面,这会限制很多应用场景。比如银行支付页面,公安验证,手机号验证,等等都需要调用第三方的H5
页面来完成的,这些页面,从小程序中就跳不过去了。
据说这个以后会放开,从小程序可以跳H5
页面,这个功能倒是值得期待。antd-mobile
是H5
页面的组件库,跟小程序是不相容的,不应该引入。不过组件思想是可以借鉴的,可以考虑以小程序的基础组件,按照antd-mobile
的样子,做一些组件出来。关于兼容性,文档中一般会有类似“基础库 1.5.0 开始支持,低版本需做兼容处理”的提示。
基础库版本可以通过接口my.SDKVersion
查看。
接口是否可用,可以通过接口my.canIUse
查看。
比如,查看收货地址,在0.15.10
的IDE
中还不支持,这时的基础库还是1.4.1
。
直接使用的话,IDE
中会提示my.chooseAddress方法ide暂不支持
,然后就中断退出了,下面的代码也不会再执行。组件方面,目前使用
template
,引入用import
;至于include
的用法就显得比较奇怪。这里的组件和React
中的组件差异很大。这里并不存在“父组件”和“子组件”之间的关系;这里是部分和整体之间的关系,最终整合为为一个对象,作为Page()
函数的参数,输入系统。对于纯展示,没有交互的简单组件,文档模板中介绍的方法够用了。不过,由于这里的数据时
data
成员中的一个对象成员,更新的时候,要更新对象的全部成员,不能只更新部分,否则其他部分会被清空,这是JS
的一个特性,需要注意。
定义模板:
<!--
index: int
msg: string
time: string
-->
<template name="msgItem">
<view>
<text> {{index}}: {{msg}} </text>
<text> Time: {{time}} </text>
</view>
</template>
使用模板:
<template is="msgItem" data="{{...item}}"/>
Page({
data: {
item: {
index: 0,
msg: 'this is a template',
time: '2016-09-15'
}
}
})
现在,想要修改msg
的值,如果只是像下面那样写,那么,index、time
两个字段就会被清空。
this.setData({
item: {
msg: 'new template',
}
}});
可以考虑下面的写法,能够达到目的:
const newItem = this.data.item;
newItem.msg = 'new template';
this.setData({
item: newItem,
});
上面这种方式会带来性能问题,不是很推荐,也可以考虑下面的方法:
this.setData({
item.msg: 'new template',
});
对于特殊字符输入,并没有转义。比如要输入“< 上一页”这样的字符,输入
'< 上一页'
是没用的。应该直接输入' < 上一页'
。注意<
前面要有字符,不然会被解释为标签,那就红屏了。至于'下一页 >'
这样的,则没有副作用,特殊字符在最后,一般没关系。view
相当于div
,是块级元素;text
相当于span
,是行内元素。默认的情况下,是普通盒子模型,是纵向的布局,这种模式下,实现文字居中,可以用这两句text-align: center; line-height: 60rpx; // 容器高度
。
如果要采用弹性盒子模型,需要加这句display: flex;
,默认是横向的布局,这种模式下,实现居中,可以用这两句justify-content: center; align-items: center;
,这种居中,不但适用于文本,也适用于图片等。
模式一:普通盒子和弹性盒子混合,特点是有些容器没有display: flex;
这句
模式二:全部采用弹性盒子模型,特点是很多地方可以看到display: flex; flex: 1;
这两句
目前来看,还是模式一比较方便;当然用模式二也是可以的。
样式,推荐用
class
,如果没有必要,style
就免了。样式,布局,逻辑分开为3个文件,这是初衷。这个和React
的JSX
是完全不同的理念。style
中可以放胡子变量,用作动态样式。静态样式,推荐用class
。当然,动态样式,也是可以用class
,方法是用胡子变量拼接字符串。比如
<text class="compareYesterday {{creditAmtFromYTDColor}}">{{creditAmtFromYTD}}</text>
拨打电话接口my.makePhoneCall(number) 在模拟器,真机上表现不一致。在模拟器上,会跳出选择对话框,选择后,也能知道选了哪个按钮,(确定还是取消)。在安卓真机上,直接跳出程序,到了拨打电话页面。在iOS真机上,会跳出选择对话框,但是用户到底选了哪个按钮,没法判断。
开发者能刷的二维码经常失效,好像代码改了,过了一定的时间,就会失效。将产品和测试都设置为开发人员,随时看页面状态,是个可行的方法。但是,二维码经常失效,带来了很大的麻烦。
如果设置为体验版,有效期是7天,并且代码改了也不会导致二维码失效。这个功能可以用来测试。比如前后台调试完成了,部署到测试服务器,通过IDE,上传一个版本,设置为体验版。把测试或者产品等相关人员设置为体验者,就可以用支付宝扫码使用了。至于提交审核,灰度和上线,可以再上传测试好的产品,同时切换到生产服务器。至于版本号,让IDE自己增长吧,做好相应的记录就好了。
对于测试人员,设置为体验人员,可以操作。不过,还是把测试人员设置为开发人员比较好。举个例子,如果测试人员用自己的支付宝账号测试,出现了bug,怎么调?如果测试人员的身份也是开发者,那么开发人员只要退出自己的IDE,用测试人员的账号登录IDE,数据、环境、复现条件都是现成的。同时,也不影响测试人员用手机进行测试。改完后,也可以马上发一个开发者的二维码,可以让测试人员马上验证一下bug是否修复。
一轮测试完成之后,将相应的bug都改掉,再发一个稳定的体验版二维码,进行一轮回归,两三轮之后估计就差不多了。包大小限制为3M,在0.17.0版本以前的IDE没事,但是之后的版本,会在本地编译打包的时候报错,无法生成真机预览的二维码。
这会带来一个明显的限制,就是npm上的第三方库就不要用了。比如,用来处理时间的moment,大小为3M多,基本上就超过限制了。
当然,一个可替代的方法是用.min.js的压缩文件替代,可能会小一点
对于隐藏文件.git不计入大小,但是对于node_modules记入大小支付宝小程序支持npm包管理,但是由于3M限制,以及IDE 0.17.0以后对于node_modules大小缺乏优化。(moment在低版本IDE可用,但是0.17.0以后就会超限)还是直接用键入js文件的方式比较好。
图片压缩接口,用IDE验证,没有作用。先my.chooseImage,然后马上用my.getImageInfo看大小;然后用my.compressImage,接着用my.getImageInfo看大小。结果发现,前后两次输出一样,没区别啊。
不过图片压缩接口my.compressImage在真机上试验还是有效果的,一般情况下,compressLevel保持默认的4就可以了上传接口my.uploadFile自带loading,不需要额外添加my.showLoading
上传接口my.uploadFile服务器返回的数据在data成员中,类型是string。只是一般服务器相应是一个对象,对错的字段都不一样。所以,这里可以考虑用JSON.parse(response.data),将字符串转化为对象后再做进一步的处理。
网络接口my.httpRequest在默认的json格式下,服务器返回的数据也在data成员中,类型是Object,不需要转化,可以直接使用。