小程序开发实战学习笔记

序言 本来题目写的时候实战经验,可是觉着算不上什么经验,就改为学习笔记了😂html

注册小程序帐号

开发和发布流程

小范围讨论公公抽离之类 前端

不写公共样式由于不知作别人会不会用你的ios

目录结构

小程序包含一个描述总体程序的 app 和多个描述各自页面的 page。

具体参见官方文档web

生命周期

onLoad(Object query)
页面加载时触发。一个页面只会调用一次,能够在 onLoad 的参数中获取打开当前页面路径中的参数。
onShow()
页面显示/切入前台时触发。
onReady()
页面初次渲染完成时触发。一个页面只会调用一次,表明页面已经准备稳当,能够和视图层进行交互。 json

注意:对界面内容进行设置的 API 如wx.setNavigationBarTitle,请在onReady以后进行。 canvas

onHide()
页面隐藏/切入后台时触发。 如 navigateTo 或底部 tab切换到其余页面,小程序切入后台等。(⚠️此处跟后面的定时器有关联)
onUnload()
页面卸载时触发。如redirectTo或navigateBack到其余页面时。(⚠️此处跟后面的定时器有关联) 小程序

⚠️注意:上传文件的时候,页面也会前后进入onHide,onShow生命周期 微信小程序

具体参见官方文档api

配置文件

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

数据传递

小程序两个页面如何接传值

正向传值 上一页面->下一页面

  1. url传值
  • 经过url传递参数到下一个页面,下一个页面在onload生命周期中经过option.来获取参数值
  1. 本地储存(后面有单独一节)
  2. 全局的app对象
  • 在一个页面中getApp().mydata = 'lnp',在另外一个页面中getApp().mydata便可
  • 在配置文件app.js中有一个叫作globalData的对象。在小程序的全部页面中均可以随时调用和写入存放在GlobalData的数据。不管是调用仍是写入,第一步都是要让页面与App.js产生关联。因此在页面的对应的JS中,第一句话就要写上:var app = getApp();

反向传值 下一页面->上一页面

  1. 本地储存(后面有单独一节)
  2. 全局的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中的函数节流和函数防抖解决。

相关文章
相关标签/搜索