20180512--芽生三月
微信官方文档:
开发文档:
https://developers.weixin.qq.com/miniprogram/dev/quickstart/basic/getting-started.html
支付文档:
https://pay.weixin.qq.com/wiki/doc/api/index.html
WX-JAVA-SDK:
https://gitee.com/binary/weixin-java-tools
经验总结:
友情提示:几乎每个踩过坑的开发者都得出这样一个结论,认真读文档,尤其提示部分。
1 框架的运行原理
- 由于框架并非运行在浏览器中,所以
JavaScript在 web 中一些能力都无法使用,如document,window等。 - 开发者写的所有代码最终将会打包成一份
JavaScript,并在小程序启动的时候运行,直到小程序销毁。类似 ServiceWorker,所以逻辑层也称之为 App Service。
1.1.目录结构
注意:为了方便开发者减少配置项,描述页面的四个文件必须具有相同的路径与文件名。
1.2.配置
pages
接受一个数组,每一项都是字符串,来指定小程序由哪些页面组成。每一项代表对应页面的【路径+文件名】信息,数组的第一项代表小程序的初始页面。小程序中新增/减少页面,都需要对 pages 数组进行修改。
注:HexColor(十六进制颜色值),如"#ff00ff"
注:navigationStyle 只在 app.json 中生效。开启 custom 后,低版本客户端需要做好兼容。开发者工具基础库版本切到 1.7.0(不代表最低版本,只供调试用) 可方便切到旧视觉
Tip:
- 当设置 position 为 top 时,将不会显示 icon
- tabBar 中的 list 是一个数组,只能配置最少2个、最多5个 tab,tab 按数组的顺序排序。
1.3逻辑层
- 增加 App 和 Page 方法,进行程序和页面的注册。
- 增加
getApp和getCurrentPages方法,分别用来获取 App 实例和当前页面栈。 - 提供丰富的 API,如微信用户数据,扫一扫,支付等微信特有能力。
- 每个页面有独立的作用域,并提供模块化能力。
- 由于框架并非运行在浏览器中,所以
JavaScript在 web 中一些能力都无法使用,如document,window等。 - 开发者写的所有代码最终将会打包成一份
JavaScript,并在小程序启动的时候运行,直到小程序销毁。类似 ServiceWorker,所以逻辑层也称之为 App Service。
前台、后台定义: 当用户点击左上角关闭,或者按了设备 Home 键离开微信,小程序并没有直接销毁,而是进入了后台;当再次进入微信或再次打开小程序,又会从后台进入前台。需要注意的是:只有当小程序进入后台一定时间,或者系统资源占用过高,才会被真正的销毁。
注意:
- 如果开发者没有添加
onPageNotFound监听,当跳转页面不存在时,将推入微信客户端原生的页面不存在提示页面 - 如果
onPageNotFound回调中又重定向到另一个不存在的页面,将推入微信客户端原生的页面不存在提示页面,并且不在回调onPageNotFound
注意:
-
App()必须在app.js中注册,且不能注册多个。 - 不要在定义于
App()内的函数中调用getApp(),使用this就可以拿到 app 实例。 - 不要在 onLaunch 的时候调用
getCurrentPages(),此时 page 还没有生成。 - 通过
getApp()获取实例之后,不要私自调用生命周期函数。
可以在 App 的 onlaunch 和 onshow 中获取上述场景值,部分场景值下还可以获取来源应用、公众号或小程序的appId。详见
Tip: 由于Android系统限制,目前还无法获取到按 Home 键退出到桌面,然后从桌面再次进小程序的场景值,对于这种情况,会保留上一次的场景值。
Page() 函数用来注册一个页面。接受一个 object 参数,其指定页面的初始数据、生命周期函数、事件处理函数等。object 内容在页面加载时会进行一次深拷贝,需考虑数据大小对页面加载的开销。
生命周期函数
-
onLoad: 页面加载- 一个页面只会调用一次,可以在 onLoad 中获取打开当前页面所调用的 query 参数。
-
onShow: 页面显示- 每次打开页面都会调用一次。
-
onReady: 页面初次渲染完成- 一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
- 对界面的设置如
wx.setNavigationBarTitle请在onReady之后设置。详见生命周期
-
onHide: 页面隐藏- 当
navigateTo或底部tab切换时调用。
- 当
-
onUnload: 页面卸载- 当
redirectTo或navigateBack的时候调用。
- 当
页面相关事件处理函数
-
onPullDownRefresh: 下拉刷新- 监听用户下拉刷新事件。
- 需要在
app.json的window选项中或页面配置中开启enablePullDownRefresh。 - 当处理完数据刷新后,
wx.stopPullDownRefresh可以停止当前页面的下拉刷新。
-
onReachBottom: 上拉触底 -
onPageScroll: 页面滚动- 监听用户滑动页面事件。
- 参数为 Object,包含以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| scrollTop | Number | 页面在垂直方向已滚动的距离(单位px) |
-
onShareAppMessage: 用户转发- 只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮
- 用户点击转发按钮的时候会调用
- 此事件需要 return 一个 Object,用于自定义转发内容
自定义转发字段
| 字段 | 说明 | 默认值 |
|---|---|---|
| title | 转发标题 | 当前小程序名称 |
| path | 转发路径 | 当前页面 path ,必须是以 / 开头的完整路径 |
注意:
- 直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。
- 单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据。
- 请不要把 data 中任何一项的 value 设为
undefined,否则这一项将不被设置并可能遗留一些潜在问题。
getCurrentPages() 函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面。
Tip:不要尝试修改页面栈,会导致路由以及页面状态错误。
-
navigateTo,redirectTo只能打开非 tabBar 页面。 -
switchTab只能打开 tabBar 页面。 -
reLaunch可以打开任意页面。 - 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
- 调用页面路由带的参数可以在目标页面的
onLoad中获取 -
tip: require 暂时不支持绝对路径
1.4 视图层
特别注意:不要直接写 checked="false",其计算结果是一个字符串,转成 boolean 类型后代表真值。
注意: 花括号和引号之间如果有空格,将最终被解析成为字符串
当 wx:for 的值为字符串时,会将字符串解析成字符串数组
wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
wx:key 的值以两种形式提供
- 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
- 保留关键字
*this代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字,如:
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
注意:<block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
特殊事件: <canvas/> 中的触摸事件不可冒泡,所以没有 currentTarget。
在组件中可以定义数据,这些数据将会通过事件传递给 SERVICE。 书写方式: 以data-开头,多个单词由连字符-链接,不能有大写(大写会自动转成小写)如data-element-type,最终在 event.currentTarget.dataset 中会将连字符转成驼峰elementType。
require函数
在.wxs模块中引用其他 wxs 文件模块,可以使用 require 函数。
引用的时候,要注意如下几点:
- 只能引用
.wxs文件模块,且必须使用相对路径。 -
wxs模块均为单例,wxs模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多次引用,使用的都是同一个wxs模块对象。 - 如果一个
wxs模块在定义之后,一直没有被引用,则该模块不会被解析与运行。
src 属性
src 属性可以用来引用其他的 wxs 文件模块。
引用的时候,要注意如下几点:
- 只能引用
.wxs文件模块,且必须使用相对路径。 -
wxs模块均为单例,wxs模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多次引用,使用的都是同一个wxs模块对象。 - 如果一个
wxs模块在定义之后,一直没有被引用,则该模块不会被解析与运行。
与 CSS 相比,WXSS 扩展的特性有:
- 尺寸单位
- 样式导入
建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。
注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。
- style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。
1.5自定义组件
注意:在组件wxss中不应使用ID选择器、属性选择器和标签名选择器。
Tips:
- 对于基础库的1.5.x版本, 1.5.7 也有部分自定义组件支持。
- 因为WXML节点标签名只能是小写字母、中划线和下划线的组合,所以自定义组件的标签名也只能包含这些字符。
- 自定义组件也是可以引用自定义组件的,引用方法类似于页面引用自定义组件的方式(使用
usingComponents字段)。 - 自定义组件和使用自定义组件的页面所在项目根目录名不能以“wx-”为前缀,否则会报错。
- 旧版本的基础库不支持自定义组件,此时,引用自定义组件的节点会变为默认的空节点。
组件对应 wxss 文件的样式,只对组件wxml内的节点生效。编写组件样式时,需要注意以下几点:
- 组件和引用组件的页面不能使用id选择器(
#a)、属性选择器([a])和标签名选择器,请改用class选择器。 - 组件和引用组件的页面中使用后代选择器(
.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用。 - 子元素选择器(
.a>.b)只能用于view组件与其子节点之间,用于其他组件可能导致非预期的情况。 - 继承样式,如
font、color,会从组件外继承到组件内。 - 除继承样式外,
app.wxss中的样式、组件所在页面的的样式对自定义组件无效。
:host 选择器(需要包含基础库 1.7.2 或更高版本的开发者工具支持)。注意:必须在两个组件定义中都加入relations定义,否则不会生效。
需要仔细阅读原文档
1.6 多线程
Tips
- Worker 最大并发数量限制为 1 个,创建下一个前请用 Worker.terminate() 结束当前 Worker
- Worker 内代码只能 require 指定 Worker 路径内的文件,无法引用其它路径
- Worker 的入口文件由 wx.createWorker() 时指定,开发者可动态指定 Worker 入口文件
- Worker 内不支持
wx系列的 API - Workers 之间不支持发送消息
小程序的功能不断的增加,但是旧版本的微信客户端并不支持新功能,所以在使用这些新能力的时候需要做兼容。
文档会在组件,API等页面描述中带上各个功能所支持的版本号。
可以通过 wx.getSystemInfo 或者 wx.getSystemInfoSync 获取到小程序的基础库版本号。
也可以通过 wx.canIUse 详情 来判断是否可以在该基础库版本下直接使用对应的API或者组件
- 小程序没有重启的概念
- 当小程序进入后台,客户端会维持一段时间的运行状态,超过一定时间后(目前是5分钟)会被微信主动销毁
- 当短时间内(5s)连续收到两次以上收到系统内存告警,会进行小程序的销毁
https://developers.weixin.qq.com/miniprogram/dev/framework/performance/tips.html
2.0 插件
https://developers.weixin.qq.com/miniprogram/dev/framework/plugin/
2.组件
注意:所有组件与属性都是小写,以连字符-连接
-
tip: 如果需要使用滚动视图,请使用 scroll-view -
使用竖向滚动时,需要给
<scroll-view/>一个固定高度,通过 WXSS 设置 height。 -
tip: 请勿在scroll-view中使用textarea、map、canvas、video组件 -
tip:scroll-into-view的优先级高于scroll-top -
tip: 在滚动scroll-view时会阻止页面回弹,所以在scroll-view中滚动,是无法触发onPullDownRefresh -
tip: 若要使用下拉刷新,请使用页面的滚动,而不是scroll-view,这样也能通过点击顶部状态栏回到页面顶部 -
tip: 如果在bindchange的事件回调函数中使用setData改变current值,则有可能导致setData被不停地调用,因而通常情况下请在改变current值前检测source字段来判断是否是由于用户触摸引起。
注意:movable-area 必须设置width和height属性,不设置默认为10px。
注意:movable-view必须在<movable-area/>组件中,并且必须是直接子节点,否则不能移动。
cover-image
覆盖在原生组件之上的文本视图,可覆盖的原生组件包括map、video、canvas、camera,只支持嵌套cover-view、cover-image。
-
tip: 基础库 1.9.90 起cover-view支持overflow: scroll,但不支持动态更新overflow -
tip: 基础库 1.9.90 起最外层cover-view支持position: fixed -
tip: 基础库 1.9.0 起支持插在view等标签下。在此之前只可嵌套在原生组件map、video、canvas、camera内,避免嵌套在其他组件内。 -
tip: 基础库 1.6.0 起支持css transition动画,transition-property只支持transform (translateX, translateY)与opacity。 -
tip: 基础库 1.6.0 起支持css opacity。 -
tip: 事件模型遵循冒泡模型,但不会冒泡到原生组件。 -
tip: 文本建议都套上cover-view标签,避免排版错误。 -
tip: 只支持基本的定位、布局、文本样式。不支持设置单边的border、background-image、shadow、overflow: visible等。 -
tip: 建议子节点不要溢出父节点 -
tip: 默认设置的样式有:white-space: nowrap;line-height: 1.2;display: block;
text
Tips
- decode可以解析的有
<>&'   - 各个操作系统的空格标准并不一致。
-
<text/>组件内只支持<text/>嵌套。 - 除了文本节点以外的其他节点都无法长按选中。
rich-text
-
tip: nodes 不推荐使用 String 类型,性能会有所下降。 -
tip:rich-text组件内屏蔽所有节点的事件。 -
tip: attrs 属性不支持 id ,支持 class 。 -
tip: name 属性大小写不敏感。 -
tip: 如果使用了不受信任的HTML节点,该节点及其所有子节点将会被移除。 -
tip: img 标签仅支持网络图片。 -
tip: 如果在自定义组件中使用rich-text组件,那么仅自定义组件的 wxss 样式对rich-text中的 class 生效。 - button
- 注1:
button-hover默认为{background-color: rgba(0, 0, 0, 0.1); opacity: 0.7;} - 注2:
bindgetphonenumber从1.2.0 开始支持,但是在1.5.3以下版本中无法使用wx.canIUse进行检测,建议使用基础库版本进行判断。 - 注3: 在
bindgetphonenumber等返回加密信息的回调中调用wx.login登录,可能会刷新登录态。此时服务器使用 code 换取的 sessionKey 不是加密时使用的 sessionKey,导致解密失败。建议开发者提前进行login;或者在回调中先使用checkSession进行登录态检查,避免login刷新登录态。
picker-view-column
仅可放置于<picker-view />中,其孩子节点的高度会自动设置成与picker-view的选中框的高度一致
textare
-
bug: 微信版本6.3.30,textarea在列表渲染时,新增加的textarea在自动聚焦时的位置计算错误。 -
tip:textarea的blur事件会晚于页面上的tap事件,如果需要在button的点击事件获取textarea,可以使用form的bindsubmit。 -
tip: 不建议在多行文本上对用户的输入进行修改,所以textarea的bindinput处理函数并不会将返回值反映到textarea上。 -
tip:textarea组件是由客户端创建的原生组件,它的层级是最高的,不能通过 z-index 控制层级。 -
tip: 请勿在scroll-view、swiper、picker-view、movable-view中使用textarea组件。 -
tip:css动画对textarea组件无效。
注:navigator-hover 默认为 {background-color: rgba(0, 0, 0, 0.1); opacity: 0.7;}, <navigator/> 的子节点背景色应为透明色
注:image组件默认宽度300px、高度225px
mode 有效值:
mode 有 13 种模式,其中 4 种是缩放模式,9 种是裁剪模式。
<video /> 默认宽度300px、高度225px,可通过wxss设置宽高。
Bug & Tip
-
tip:camera组件是由客户端创建的原生组件,它的层级是最高的,不能通过 z-index 控制层级。可使用cover-viewcover-image覆盖在上面。 -
tip: 同一页面只能插入一个camera组件。 -
tip: 请勿在scroll-view、swiper、picker-view、movable-view中使用camera组件。
live-player&live-pusher 需要流地址.
map
注意: covers 属性即将移除,请使用 markers 替代
Bug & Tip
-
tip:map组件是由客户端创建的原生组件,它的层级是最高的,不能通过 z-index 控制层级。 -
tip: 请勿在scroll-view、swiper、picker-view、movable-view中使用map组件。 -
tip:css动画对map组件无效。 -
tip:map组件使用的经纬度是火星坐标系,调用wx.getLocation接口需要指定type为gcj02
canvas
注:
- canvas 标签默认宽度300px、高度225px
- 同一页面中的 canvas-id 不可重复,如果使用一个已经出现过的 canvas-id,该 canvas 标签对应的画布将被隐藏并不再正常工作
web-view
Bug & Tip
- 网页内iframe的域名也需要配置到域名白名单。
- 开发者工具上,可以在
<web-view/>组件上通过右键 - 调试,打开<web-view/>组件的调试。 - 每个页面只能有一个
<web-view/>,<web-view/>会自动铺满整个页面,并覆盖其他组件。 -
<web-view/>网页与小程序之间不支持除JSSDK提供的接口之外的通信。 - 在iOS中,若存在JSSDK接口调用无响应的情况,可在
<web-view/>的src后面加个#wechat_redirect解决。
3.API
3.1发请求
最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String 。转换规则如下:
- 对于
GET方法的数据,会将数据转换成 query string(encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...) - 对于
POST方法且header['content-type']为application/json的数据,会对数据进行 JSON 序列化 - 对于
POST方法且header['content-type']为application/x-www-form-urlencoded的数据,会将数据转换成 query string (encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...)
Bug & Tip
-
tip: content-type 默认为 'application/json'; -
tip: url 中不能有端口; -
bug: 开发者工具0.10.102800版本,header的content-type设置异常;