序言 原本题目写的时候实战经验,但是觉着算不上什么经验,就改成学习笔记了?
注册小程序账号
开发和发布流程
小范围讨论公公抽离之类
不写公共样式因为不知道别人会不会用你的
目录结构
小程序包含一个描述整体程序的 app 和多个描述各自页面的 page。
具体参见官方文档
生命周期
onLoad(Object query)
页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数。
onShow()
页面显示/切入前台时触发。
onReady()
页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
注意:对界面内容进行设置的 API 如wx.setNavigationBarTitle,请在onReady之后进行。
onHide()
页面隐藏/切入后台时触发。 如 navigateTo 或底部 tab切换到其他页面,小程序切入后台等。(⚠️此处跟后面的定时器有关联)
onUnload()
页面卸载时触发。如redirectTo或navigateBack到其他页面时。(⚠️此处跟后面的定时器有关联)
⚠️注意:上传文件的时候,页面也会先后进入onHide,onShow生命周期
配置文件
app.json和pages文件夹里的json文件的一个区别
app.json
{
"pages": [
"pages/index/index"
],
"window": {
"backgroundTextStyle": "light"
},
"networkTimeout": {
"request": 10000
}
}
pages文件夹里的json文件只有一层,因为页面的.json只能设置 window 相关的配置项,以决定本页面的窗口表现,所以无需写 window 这个键。
{
"navigationBarTitleText": "订单详情"
}
project.config.json文件是项目配置(工具配置)文件
通常大家在使用一个工具的时候,都会针对各自喜好做一些个性化配置,例如界面颜色、编译配置等等,在小程序开发者工具上做的任何配置都会写入到这个文件,当你重新安装工具或者换电脑工作时,你只要载入同一个项目的代码包,开发者工具就自动会帮你恢复到当时你开发项目时的个性化配置,其中会包括编辑器的颜色、代码上传时自动压缩等等一系列选项。包括基础库版本,项目的appid,项目名字等。
另外,如果修改编译模式,那么增减的编译模式会反映在project.config.json文件的condition-miniprogram-list数组里。可能测试在测的时候或者协同开发的时候别人有修改,影响了这个文件最好不要提交。
具体参见官方文档
快捷键
列举几个提升开发效率的常用快捷键**
- ⌘ + N ctrl + N 新建文件
- ⌘ + S ctrl + S 保存文件
- ⇧ + ⌘ + S shift + ctrl + S 保存所有文件
- ⌘ + Z ctrl + Z 撤销
- ⇧ + ⌘ + Z shift + ctrl + Z 重做
- ⇧ + ⌥ + F shift + alt + F 格式化代码
- ⌘ + F ctrl + F 文件内搜索
- ⇧ + ⌘ + F shift + ctrl + F 项目内搜索
- ⌘ + B ctrl + B 编译项目
wxss
与 CSS 相比,WXSS 扩展的特性有:尺寸单位 样式导入
尺寸单位
rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
⚠️开发微信小程序时设计师最好用 iPhone6 作为视觉稿的标准。这样好计算,乘以2就可以了。
样式导入
使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。
目前支持的选择器
目前支持的选择器有:.class,#id,element,element, element,::after,::before。
eg.箭头之类的小图标可以用伪类写。
其他
没有嵌套
background-image设置背景图片:只支持线上图片和base64图片,不支持本地图片
wxml
列表渲染
多层渲染
使用 wx:for-item 可以指定数组当前元素的变量名,使用 wx:for-index 可以指定数组当前下标的变量名。
如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
⚠️但是仍然建议使用 wx:key 来指定列表中项目的唯一的标识符。
代码中的 " " 和 ' '
小程序中wxml中设置wxss变量等情况时,注意 " " 和 ' ' 之间的嵌套关系。
关于<block/>
小程序中的<block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个<block/>
标签将多个组件包装起来,并在上边使用 wx:if 控制属性。
类似 block wx:if,也可以将 wx:for 用在<block/>标签上,以渲染一个包含多节点的结构块。
关于 wx:if 和 hidden
因为 wx:if 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
组件
icon
size 单位px
text
text中的内容不确定的时候,注意添加样式word-break: break-all;
否则,内容全是数字时会溢出text。
image
binderror:当错误发生时,发布到 AppService 的事件名,事件对象event.detail = {errMsg: 'something wrong'}
坑:当找不到图片时才会执行,如果后台没有返回这个字段,src中为空的时候不会执行。
textarea
开发调试过程中会发现textarea 浮在最上面。关于这个问题:
该组件是原生组件,使用时请注意相关限制。
关于原生组件
由于原生组件脱离在 WebView 渲染流程外,因此在使用时有以下限制:
原生组件的层级是最高的,所以页面中的其他组件无论设置 z-index 为多少,都无法盖在原生组件上。
后插入的原生组件可以覆盖之前的原生组件。
原生组件还无法在 scroll-view、swiper、picker-view、movable-view 中使用。
部分CSS样式无法应用于原生组件,例如:
无法对原生组件设置 CSS 动画
无法定义原生组件为 position: fixed
不能在父级节点使用 overflow: hidden 来裁剪原生组件的显示区域
原生组件的事件监听不能使用 bind:eventname 的写法,只支持 bindeventname。原生组件也不支持 catch 和 capture 的事件绑定方式在iOS下,原生组件暂时不支持触摸相关事件。
坑:在开发过程中遇到的问题,如果一个输入框中的文字过多,显示不完全,在ios真机上是无法左右滑动文字查看的。在开发工具上可以,原因见下一条。
⚠️注意 真机与开发工具的表现
在工具上,原生组件是用web组件模拟的,因此很多情况并不能很好的还原真机的表现,建议开发者在使用到原生组件时尽量在真机上进行调试。
目前原生组件有:camera canvas input live-player live-pusher map textarea video
数据传递
小程序两个页面如何接传值
正向传值 上一页面->下一页面
- url传值
- 通过url传递参数到下一个页面,下一个页面在onload生命周期中通过option.来获取参数值
- 本地储存(后面有单独一节)
- 全局的app对象
- 在一个页面中
getApp().mydata = 'lnp'
,在另一个页面中getApp().mydata
即可 - 在配置文件app.js中有一个叫做
globalData
的对象。在小程序的所有页面中都可以随时调用和写入存放在GlobalData的数据。无论是调用还是写入,第一步都是要让页面与App.js产生关联。所以在页面的对应的JS中,第一句话就要写上:var app = getApp();
,
反向传值 下一页面->上一页面
- 本地储存(后面有单独一节)
- 全局的app对象
<!--### 组件中传值-->
跳转
为了不让用户在使用小程序时造成困扰,请尽量避免多层级的交互方式。
⚠️注意:目前页面路径最多只能十层。
导航api
wx.navigateTo(OBJECT)
保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面。(非 tabBar 的页面的路径 ;路径后可以带参数)
wx.redirectTo(OBJECT)
关闭当前页面,跳转到应用内的某个页面。(非 tabBar 的页面的路径 ;路径后可以带参数)
wx.reLaunch(OBJECT)
关闭所有页面,打开到应用内的某个页面。(可以打开任意页面,包括tabBar 页面;路径后可以带参数;跳转的页面路径是 tabBar 页面则不能带参数。跳转到的页面不能返回,因此最好用在返回至首页的的时候)
wx.switchTab(OBJECT)
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面(需要跳转的 tabBar 页面的路径必须是 app.json 的 tabBar 字段定义的页面,否则无效,路径后不能带参数)
wx.navigateBack(OBJECT)
关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。
wx.navigateBack({
delta: 2
})
⚠️注意:调用 navigateTo 跳转时,调用该方法的页面会被加入堆栈,而 redirectTo 方法则不会
navigator组件
navigator组件的open-type属性值规定页面的跳转方式,navigate,redirect,switchTab,reLaunch,navigateBack与api相对应。
详见文档
坑:比如有的小程序底部的tabBar有一个‘我的’功能有未读消息红点的需求,所以无法使用小程序原本的tab。自定义的tabBar中 <navigator class="tab-item" url="/pages/home/index/index" open-type="redirect"
>需要添加open-type="redirect"
,否则页面会被加入堆栈,用户切换tab多次会导致页面无法跳转。但是添加该属性存在一个问题,在开发工具上会明显看到页面先跳转到index页面,再跳转到目标页面,在真机上表现为闪一下,该问题目前未解决。
跳转到h5
使用web-view组件,基础库 1.6.4 开始支持,低版本需做兼容处理。
⚠️注意:
- 个人类型与海外类型的小程序暂不支持使用。
- 每个页面只能有一个web-view组件,
<web-view/>
会自动铺满整个页面,并覆盖其他组件。
当需要跳转到的url过长时,无法通过url参数携带,可以通过本地存储保存。
api相关
wx.nextTick(FUNCTION)
基础库 2.2.3 开始支持,低版本需做兼容处理。用于延迟一部分操作到下一个时间片再执行(类似于 setTimeout)。
因为自定义组件中的 setData 和 triggerEvent 等接口本身是同步的操作,当这几个接口被连续调用时,都是在一个同步流程中执行完的,因此若逻辑不当可能会导致出错。
Component({
doSth() {
this.setData({ number: 1 }) // 直接在当前同步流程中执行
wx.nextTick(() => {
this.setData({ number: 3 }) // 在当前同步流程结束后,下一个时间片执行
})
this.setData({ number: 2 }) // 直接在当前同步流程中执行
}
})
//1 2 3
本地存储
每个微信小程序都可以有自己的本地缓存,可以通过 wx.setStorage(wx.setStorageSync)、wx.getStorage(wx.getStorageSync)、wx.clearStorage(wx.clearStorageSync)可以对本地缓存进行设置、获取和清理。同一个微信用户,同一个小程序 storage 上限为 10MB。localStorage 以用户维度隔离,同一台设备上,A 用户无法读取到 B 用户的数据。注意: 如果用户储存空间不足,我们会清空最近最久未使用的小程序的本地缓存。我们不建议将关键信息全部存在 localStorage,以防储存空间不足或用户换设备的情况。
详细请看接口文档,写的很详细。
//设置
wx.setStorage({
key: 'mykey',
data: 'lnp'
})
//获取
wx.getStorageSync('mykey'),
定时器
清除定时器需要注意在页面卸载和隐藏/进入后台时都要清除。
// redirectTo或navigateBack离开时触发
onUnload: function() {
clearInterval(countDownTimer)
},
// navigateTo 离开时触发
onHide: function() {
clearInterval(countDownTimer)
}
支付
付款的时候点击叉,都是支付失败,但是可以通过fail中返回的res.errMsg == 'requestPayment:fail cancel'
与否来判断是否是用户主动取消支付。
原本说上线才能测试支付,但是后台配置了之后也可以测试。
详见文档
音频
移步文档
微信小程序获取音频时长
const innerAudioContext = wx.createInnerAudioContext()
innerAudioContext.src = 'http://kano.guahao-test.com/orT27672955?token=V1.0_Vi9tRHZQbE9mZXRzUVd5UDhaazBVQT09X1RJTUVfQUVTCOUSTOM&convert=1'
innerAudioContext.onCanplay(() => {
console.log("语音时长预获取:" + innerAudioContext.duration)
})//这一段必须有 不然没法获取时长 删掉console.log也不行
setTimeout(() => {
console.log("语音时长获取:" + innerAudioContext.duration)//2.795102
}, 1000)
备注:关于这个没有在真机上测试,也没有在项目中使用,因为可能涉及流量消耗的问题在真机上这个方法会被阻止掉,日后知道更多再更新此问题。
内存泄露
跳转页面传值多次来回点击就会报错,但不影响页面。官方回复为基础库的已知问题
eventemitter 的 warning,没影响,也不会实际泄露。
移步开发者社区
注意
设置data数据
setData 函数用于将数据从逻辑层发送到视图层,同时改变对应的 this.data 的值。注意:
(1)直接修改 this.data 无效,不会重新渲染page,还会造成数据不一致。
(2)单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据。
this赋值
方法中给this赋值,const _this = this
, 应对变量提升等问题
表单提交
formId
前台获取 formId 送至后台,由后台实现模板消息的发送。(此处由于 formId 只能由用户触发表单提交操作产生,故前台需要将每次产生的formId发送至后台,由后台保存并在适当时候调用微信接口向用户发送模板消息)
注意:因为我们是在开发者工具中测试,所以得到的formId值为the formId is a mock one。在真机中我们可以得到一个具体的值,利用该值结合其他参数就可以发送模板消息啦,所以测试真实场景务必在真机中测试。
坑:开始的做法是先e.detail.formId获取formId,保存到form的隐藏input里,然后再提交,这样做会导致第一次点击提交的时候获取不到formId的值。后来用这种方法直接传值是可以的。
data: Object.assign(e.detail.value,{
formId: e.detail.formId//formId 用于发送模板消息
}),
避免表单重复提交
有时候接口请求慢,需要注意禁止重复提交的问题。
兼容
ios上new Date()时间格式处理
在ios上new Date(expiredTimeNormalIos)
中的参数如果直接用后台返回的 “2017-11-11 11:11:11”时间格式,不支持,会直接返回null,需要转化成可以兼容的格式,如下
let expiredTimeNormalIos = expiredTimeNormal.replace(/\-/g, '/')
//时间格式兼容ios 2014-09-25T13:24:00
input在华为mate8上显示问题
与布局有关
toast
低版本,如果配置none,最后显示还是勾
iphone x
<!--app.js-->
globalData: {
isIphoneX: false,//判断是否是iphone x以便兼容
}
onShow: function () {
const _this = this
//判断设备类型
wx.getSystemInfo({
success: function (res) {
//console.log(res.model)
if (res.model.search('iPhone X') != -1) {//判断方法不能写res.model==iPhone X,因为真机上返回的是一个包含iPhone X字段的详细设备类型
_this.globalData.isIphoneX = true
}
}
})
},
<!--app.wxss-->
/* 适配iphone x 吸底按钮 */
.fix-iphonex-button {
bottom:68rpx!important;
}
.fix-iphonex-button::after {
content: ' ';
position: fixed;
bottom: 0!important;
height: 68rpx!important;//关于68rpx是根据iphone x和其他设备宽高对比得出来的,亲测有效
width: 100%;
background: #fff;
}
.fix-iphonex-pb{
padding-bottom:68rpx!important;//修改了底部的bottom可能会影响其他布局,视情况添加其他样式
}
其他
更改appId 需要在项目上改,单在配置文件中改无效,同样别人更新的时候需要拉取代码,然后新建项目。
图片上传服务器的域名需要后台配置
报错:未绑定为第三方平台的开发小程序。是因为解除绑定,需要重新添加项目。
刚开始开发的时候发现在个别安卓机上不能预览(比如锤子手机?)
发布的时候域名要是https
上线前把开发调试时候的无用编译模式删掉,或者保留有效的入口和参数名以便模拟调试
接口域名切换成线上地址
线上图片如果有cdn缓存,前端设置图片的时候需要在图片路径后添加参数,否则更换了图片在移动设备上比较难清缓存
发现一个小bug,不知道是不是小程序自己的问题:图片路径后加参数和不加参数,在mode="widthFix"模式下如<image style='width:40rpx;' mode="widthFix" src=""></image>
时,高度计算的结果是不一样的。
待完善...
当网络条件差或卡顿的情况下,用户多次点击,出现多次跳转页面等情况,可以通过JS中的函数节流和函数防抖解决。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。