微信小程序开发经验总结

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 中一些能力都无法使用,如 documentwindow 等。
  • 开发者写的所有代码最终将会打包成一份 JavaScript,并在小程序启动的时候运行,直到小程序销毁。类似 ServiceWorker,所以逻辑层也称之为 App Service。

关于ServiceWorker

1.1.目录结构

注意:为了方便开发者减少配置项,描述页面的四个文件必须具有相同的路径与文件名。

1.2.配置

pages

接受一个数组,每一项都是字符串,来指定小程序由哪些页面组成。每一项代表对应页面的【路径+文件名】信息,数组的第一项代表小程序的初始页面。小程序中新增/减少页面,都需要对 pages 数组进行修改。

注:HexColor(十六进制颜色值),如"#ff00ff"

注:navigationStyle 只在 app.json 中生效。开启 custom 后,低版本客户端需要做好兼容。开发者工具基础库版本切到 1.7.0(不代表最低版本,只供调试用) 可方便切到旧视觉

Tip:

  1. 当设置 position 为 top 时,将不会显示 icon
  2. tabBar 中的 list 是一个数组,只能配置最少2个、最多5个 tab,tab 按数组的顺序排序。

1.3逻辑层

  • 增加 App 和 Page 方法,进行程序和页面的注册。
  • 增加 getApp 和 getCurrentPages 方法,分别用来获取 App 实例和当前页面栈。
  • 提供丰富的 API,如微信用户数据,扫一扫,支付等微信特有能力。
  • 每个页面有独立的作用域,并提供模块化能力。
  • 由于框架并非运行在浏览器中,所以 JavaScript 在 web 中一些能力都无法使用,如 documentwindow 等。
  • 开发者写的所有代码最终将会打包成一份 JavaScript,并在小程序启动的时候运行,直到小程序销毁。类似 ServiceWorker,所以逻辑层也称之为 App Service。

前台、后台定义: 当用户点击左上角关闭,或者按了设备 Home 键离开微信,小程序并没有直接销毁,而是进入了后台;当再次进入微信或再次打开小程序,又会从后台进入前台。需要注意的是:只有当小程序进入后台一定时间,或者系统资源占用过高,才会被真正的销毁。

注意:

  1. 如果开发者没有添加 onPageNotFound 监听,当跳转页面不存在时,将推入微信客户端原生的页面不存在提示页面
  2. 如果 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: 页面卸载

    • redirectTonavigateBack的时候调用。

页面相关事件处理函数

  • onPullDownRefresh: 下拉刷新

    • 监听用户下拉刷新事件。
    • 需要在app.jsonwindow选项中或页面配置中开启enablePullDownRefresh
    • 当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。
  • onReachBottom: 上拉触底

    • 监听用户上拉触底事件。
    • 可以在app.jsonwindow选项中或页面配置中设置触发距离onReachBottomDistance
    • 在触发距离内滑动期间,本事件只会被触发一次。
  • onPageScroll: 页面滚动

    • 监听用户滑动页面事件。
    • 参数为 Object,包含以下字段:
字段类型说明
scrollTopNumber页面在垂直方向已滚动的距离(单位px)
  • onShareAppMessage: 用户转发
    • 只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮
    • 用户点击转发按钮的时候会调用
    • 此事件需要 return 一个 Object,用于自定义转发内容

自定义转发字段

字段说明默认值
title转发标题当前小程序名称
path转发路径当前页面 path ,必须是以 / 开头的完整路径

注意:

  1. 直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致
  2. 单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据
  3. 请不要把 data 中任何一项的 value 设为 undefined ,否则这一项将不被设置并可能遗留一些潜在问题。

getCurrentPages() 函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面。

Tip:不要尝试修改页面栈,会导致路由以及页面状态错误。

  • navigateToredirectTo 只能打开非 tabBar 页面。
  • switchTab 只能打开 tabBar 页面。
  • reLaunch 可以打开任意页面。
  • 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
  • 调用页面路由带的参数可以在目标页面的onLoad中获取

  • tip: require 暂时不支持绝对路径

1.4 视图层

特别注意:不要直接写 checked="false",其计算结果是一个字符串,转成 boolean 类型后代表真值。

注意: 花括号和引号之间如果有空格,将最终被解析成为字符串

当 wx:for 的值为字符串时,会将字符串解析成字符串数组

如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。

wx:key 的值以两种形式提供

  1. 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
  2. 保留关键字 *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
  1. Worker 最大并发数量限制为 1 个,创建下一个前请用 Worker.terminate() 结束当前 Worker
  2. Worker 内代码只能 require 指定 Worker 路径内的文件,无法引用其它路径
  3. Worker 的入口文件由 wx.createWorker() 时指定,开发者可动态指定 Worker 入口文件
  4. Worker 内不支持 wx 系列的 API
  5. Workers 之间不支持发送消息


1.7 兼容

小程序的功能不断的增加,但是旧版本的微信客户端并不支持新功能,所以在使用这些新能力的时候需要做兼容。

文档会在组件,API等页面描述中带上各个功能所支持的版本号。

可以通过 wx.getSystemInfo 或者 wx.getSystemInfoSync 获取到小程序的基础库版本号。

也可以通过 wx.canIUse 详情 来判断是否可以在该基础库版本下直接使用对应的API或者组件


1.8 运行机制

  • 小程序没有重启的概念
  • 当小程序进入后台,客户端会维持一段时间的运行状态,超过一定时间后(目前是5分钟)会被微信主动销毁
  • 当短时间内(5s)连续收到两次以上收到系统内存告警,会进行小程序的销毁
1.9 代码优化

https://developers.weixin.qq.com/miniprogram/dev/framework/performance/tips.html

2.0 插件

https://developers.weixin.qq.com/miniprogram/dev/framework/plugin/

2.组件

注意:所有组件与属性都是小写,以连字符-连接

  1. tip: 如果需要使用滚动视图,请使用 scroll-view
  2. 使用竖向滚动时,需要给<scroll-view/>一个固定高度,通过 WXSS 设置 height。
  3. tip: 请勿在 scroll-view 中使用 textareamapcanvasvideo 组件
  4. tipscroll-into-view 的优先级高于 scroll-top
  5. tip: 在滚动 scroll-view 时会阻止页面回弹,所以在 scroll-view 中滚动,是无法触发 onPullDownRefresh
  6. tip: 若要使用下拉刷新,请使用页面的滚动,而不是 scroll-view ,这样也能通过点击顶部状态栏回到页面顶部
  7. tip: 如果在 bindchange 的事件回调函数中使用 setData 改变 current 值,则有可能导致 setData 被不停地调用,因而通常情况下请在改变 current 值前检测 source 字段来判断是否是由于用户触摸引起。

注意:movable-area 必须设置width和height属性,不设置默认为10px。

注意:movable-view必须在<movable-area/>组件中,并且必须是直接子节点,否则不能移动。

cover-image

覆盖在原生组件之上的文本视图,可覆盖的原生组件包括mapvideocanvascamera,只支持嵌套cover-viewcover-image

  1. tip: 基础库 1.9.90 起 cover-view 支持 overflow: scroll,但不支持动态更新 overflow
  2. tip: 基础库 1.9.90 起最外层 cover-view 支持 position: fixed
  3. tip: 基础库 1.9.0 起支持插在 view 等标签下。在此之前只可嵌套在原生组件mapvideocanvascamera内,避免嵌套在其他组件内。
  4. tip: 基础库 1.6.0 起支持css transition动画,transition-property只支持transform (translateX, translateY)opacity
  5. tip: 基础库 1.6.0 起支持css opacity。
  6. tip: 事件模型遵循冒泡模型,但不会冒泡到原生组件。
  7. tip: 文本建议都套上cover-view标签,避免排版错误。
  8. tip: 只支持基本的定位、布局、文本样式。不支持设置单边的borderbackground-imageshadowoverflow: visible等。
  9. tip: 建议子节点不要溢出父节点
  10. tip: 默认设置的样式有:white-space: nowrap; line-height: 1.2; display: block;
text
Tips
  • decode可以解析的有 &nbsp; &lt; &gt; &amp; &apos; &ensp; &emsp;
  • 各个操作系统的空格标准并不一致。
  • <text/> 组件内只支持 <text/> 嵌套。
  • 除了文本节点以外的其他节点都无法长按选中。

rich-text

  1. tip: nodes 不推荐使用 String 类型,性能会有所下降。
  2. tiprich-text 组件内屏蔽所有节点的事件。
  3. tip: attrs 属性不支持 id ,支持 class 。
  4. tip: name 属性大小写不敏感。
  5. tip: 如果使用了不受信任的HTML节点,该节点及其所有子节点将会被移除。
  6. tip: img 标签仅支持网络图片。
  7. tip: 如果在自定义组件中使用 rich-text 组件,那么仅自定义组件的 wxss 样式对 rich-text 中的 class 生效。
  8. 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

  1. bug: 微信版本 6.3.30textarea 在列表渲染时,新增加的 textarea 在自动聚焦时的位置计算错误。
  2. tiptextarea 的 blur 事件会晚于页面上的 tap 事件,如果需要在 button 的点击事件获取 textarea,可以使用 form 的 bindsubmit
  3. tip: 不建议在多行文本上对用户的输入进行修改,所以 textarea 的 bindinput 处理函数并不会将返回值反映到 textarea 上。
  4. tiptextarea 组件是由客户端创建的原生组件,它的层级是最高的,不能通过 z-index 控制层级。
  5. tip: 请勿在 scroll-viewswiperpicker-viewmovable-view 中使用 textarea 组件。
  6. tipcss 动画对 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
  1. tipcamera 组件是由客户端创建的原生组件,它的层级是最高的,不能通过 z-index 控制层级。可使用 cover-view cover-image覆盖在上面。
  2. tip: 同一页面只能插入一个 camera 组件。
  3. tip: 请勿在 scroll-viewswiperpicker-viewmovable-view 中使用 camera 组件。

live-player&live-pusher 需要流地址.

map

注意: covers 属性即将移除,请使用 markers 替代

Bug & Tip
  1. tipmap 组件是由客户端创建的原生组件,它的层级是最高的,不能通过 z-index 控制层级。
  2. tip: 请勿在 scroll-viewswiperpicker-viewmovable-view 中使用 map 组件。
  3. tipcss 动画对 map 组件无效。
  4. tipmap 组件使用的经纬度是火星坐标系,调用 wx.getLocation 接口需要指定 type 为 gcj02

canvas

注:

  1. canvas 标签默认宽度300px、高度225px
  2. 同一页面中的 canvas-id 不可重复,如果使用一个已经出现过的 canvas-id,该 canvas 标签对应的画布将被隐藏并不再正常工作

web-view
Bug & Tip
  1. 网页内iframe的域名也需要配置到域名白名单。
  2. 开发者工具上,可以在 <web-view/> 组件上通过右键 - 调试,打开 <web-view/> 组件的调试。
  3. 每个页面只能有一个<web-view/><web-view/>会自动铺满整个页面,并覆盖其他组件。
  4. <web-view/>网页与小程序之间不支持除JSSDK提供的接口之外的通信。
  5. 在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
  1. tip: content-type 默认为 'application/json';
  2. tip: url 中不能有端口;
  3. bug: 开发者工具 0.10.102800 版本,header 的 content-type 设置异常;
canvas:



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值