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-view
cover-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
设置异常;