微信小程序开发技巧总结

2,541 阅读8分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

前言

近期开发了微信小程序的项目,也遇到了一些问题,再次记录下来,看看大家师父也有遇到过类似的。

修改对象、数组中某一项

小程序里面通常会有这样类似的需求,比如对一个数组进行选择或则其他操作等。

修改对象中某一项

修改对象中某一项会比较简单一点,直接将对象的某一个属性使用中括号即可。例如:

this.setData({
  ['params.type']: ''
})

这样就可以单独的修改对象中某一个属性的值,而不用全部修改。

修改数组中某一项的值

修改数组中对象的某一个值稍微麻烦一点,毕竟我们需要知道修改的值的下标,知道了下标和上面的对象差不多,唯一不同在于需要再key部分需要加入变量,所以最终写法如下:

this.setData({
  ["tableData[" + index + "].coverPic"]: "../../images/img_error.png"
})

上面例子中index为数组下标,就是修改数组中某一个对象的coverPic的值

canvas画图片需要先下载图片

这个需求也很常见,比如在做分享到朋友圈的时候我们需要通过canvas来画一张拉新的图片,所以图片上面需要带一张二维码,当我们从后台获取到二维码后,如果直接就通过api画到canvas上是不行的,需要先通过api下载后才可以。

canvas生成图片后保存

通过canvas生成的图片通常我们都会保存到用户的手机里面,再让用户去发送给别人拉新,保存图片的时候就变成了概率事件了,有时候能保存成功,有的时候不能保存成功,这个问题其实就是需要我们在生产draw方法的回调里面去保存图才能保证成功。

wx.request获取cookie的值

在微信的发送请求的api中有的时候需要我们自己去获取cookie的值来和后端进行通讯,我们知道Vue是获取不到的,那么小程序是可以获取到的,怎么获取呢?如果大家有注意观察这个api返回的数据就知道其实获取cookie很简单,如下:

res.header["Set-Cookie"]

上面的res为请求接口成功后的返回值

使用WEUI某几个组件

我们知道小程序的扩展能力里面是可以直接使用WEUI的,那么除了官方的通过useExtendedLib来使用外,其实我们还可以自己引入来使用,比如我们需要使用WEUI里面的Slideview、HalfScreenDialog、ActionSheet这三个组件,通常这三个组件的使用率还是很高的,那么我们可以自己到WEUI的github仓库拷贝自己想要的组件到自己的项目中当做普通组件使用即可。

app.js里面可以自定义工具

通常小程序如果有需要用到自己写的工具函数的时候,我们就是在哪个页面需要就在按个页面导入,特别是使用相对路径的时候比较麻烦,其实我们完全可以在小程序的app.js里面引入后挂载到app上,这样需要用到的页面只需要通过getApp().utils即可使用啦,如:

import utils from './utils/utils.js'
App({
  globalData: {
    userInfo: null,
    systemInfo: null,
  },
  $utils:utils
});

// 页面使用
getApp().$utils.formateDate()

globalData里面也是可以定义一些常用数据或者公共的方便其他页面使用

小程序地址传值不能太长,太长会被截取

小程序中的地址后面携带参数时,如果参数特别多的话,一旦超出就会截取导致出现意想不到的错误,其实这里和网页是一样的,地址栏后面携带参数是有限制的。

小程序代码包限制

小程序的代码包是有限制的,这个大家通过官方也可以查到,通常整个小程序所有分包大小不超过20M、单个分包/主包大小不能超过2M,所以一旦你的项目比较大的话要提前规划,做好分包,这样能够分散包的大小,而且这样对小程序的性能也会更好。

小程序自定义事件参数

微信小程序中事件是不能携带其他参数的,那么通常我们是需要它能够携带参数才方便我们进行相应操作的,那么这个携带参数其实就是在结构上面添加自定义属性,如data-index等,然后通过点击事件的事件对象来获取这个自定义属性的值,例子如下:

<button bindtap="openLocation" data-lat="30.49984" data-lot="114.34253">打开导航</button>

openLocation(e) {
  wx.openLocation({
    latitude: Number(e.currentTarget.dataset.lat),
    longitude: Number(e.currentTarget.dataset.lot),
  })
}

设置整个页面的样式

开发微信小程序的时候有时需要设置整个页面的样式,但又不想自己加一个标签,那么我们可以在样式里面这样设置接口,如下:

page{
  background:#FF4400;
}

block

微信小程序中block标签和Vue中的template一样的,不需要新加标签的情况下使用block,渲染后就能够达到多个并列的标签了,比如在做循环的时候:

<block wx:for="{{[1, 2, 3]}}">
  <view> {{index}}: </view>
  <view> {{item}} </view>
</block>

wx:if vs hidden

在小程序中使用wx-if,是基于局部渲染的形式。比如wx:if初始渲染条件为false时,框架什么都不会做;只有为真的时候才开始渲染该组件。而使用hidden在初始的时候就会渲染,它的值只是负责该组件的显示与隐藏。因此在切换的时候,wx:if有更高的性能消耗,当我们项目需要频繁切换时,建议把wx:if换成了hidden。

常量或者一些不怎么变化的都可以不用放在data里面

小程序里面的data数据太多也会影响小程序的性能的,所以不是任何东西都需要放到data里面,其实我们还可以放到最外层,如:

const app = getApp()
let pageIndex = 1
let pageSize = 10
Page({
  data:{}
})

webview里面的网址必须在公众平台设置白名单

这个限制相信大部分都知道,如果没有这个限制的话,估计很多网页版的都可以直接搬到小程序上,甚至还可以引用别人的网站上的东西,所以为了防止这种事情发生,微信做了限制,必须在公众平台配置域名白名单,只有在白名单里面的网址才能在webview里面访问。

分享中使用异步不生效

小程序的分享是在页面的一个函数里面,在这个函数里面分享的时候是使用异步是不生效的,其实这里当我们点击分享的时候很快就分享出去了,如果用了一个异步请求啥的估计就慢了,所以使用异步是不能阻止分享的,但是我们可以在里面进行一些异步的调用,至于是那个先运行就不清楚了。

复合码解码

有的时候在做小程序的时候需要使用普通的二维码来作为小程序引流码,那么这种码在获取参数的时候是需要对url进行解码的,如下:

decodeURIComponent(options.q)

开发者工具可以通过二维码编译以及参数编译

做过支付宝小程序后就会发现,微信小程序确实要比支付宝方便很多,就这个功能目前支付宝是没有的,后面估计会添加,入口如下: 1.jpg

wx.requestPayment判断失败和取消

小程序的支付api返回的不是像通常我们的接口那样,返回标识的,小程序的取消支付是需要自己去对字符串进行操作的,如小程序返回的信息是errMsg: "requestPayment:fail cancel",在通过这个信息中fail cancel来判读是否取消。

WXS

wxs是小程序的一种脚本语言,大致和js差不多,但是没有js强大,这里不介绍脚本本身,单独说说如何使用,其实当我们在页面上有些数据需要格式化或者其他运算操作的时候就可以使用这个wxs,有点类似Vue里面的计算属性,使用很简单就是引入即可使用,这里有两种定义方法,一种是直接在wxml里面,一种是单独的文件。所以如果只是个别页面需要单独的格式化或者其他运算可以采用这种方案。

直接在wxml里面定义

这里大家可以直接看看官方的例子

<wxs module="foo">
var some_msg = "hello world";
module.exports = {
  msg : some_msg,
}
</wxs>
<view> {{foo.msg}} </view>

单独文件.wxs

如果是单独的文件,那么后缀名为.wxs,使用如下:

<wxs src="./../comm.wxs" module="some_comms"></wxs>

<!-- 调用 some_comms 模块里面的 bar 函数,且参数为 some_comms 模块里面的 foo -->
<view> {{some_comms.bar(some_comms.foo)}} </view>

模板复用

小程序也提供给了一个叫做代码片段的模板,这种模板就相当于如果多个地方用到只需要写一份就可以,其他地方需要引用就好了。

<template name="msgItem">
  <view>
    <text> {{index}}: {{msg}} </text>
    <text> Time: {{time}} </text>
  </view>
</template>

<template is="msgItem" data="{{...item}}"/>