小程序踩坑日记

296 阅读4分钟

真的是不明白小程序为什么这么多无形又致命的大坑。。。难道是开源大哥老板没发工资(手动滑稽)?不想了,为了以后不会掉进同样的坑里,还是老老实实记下埋坑点。。。

列表渲染

小程序列表渲染用的是wx:for,默认循环元素是item,索引是index,手动设置为wx:for-itemwx:for-index。这些都还算正常,但是坑在于数组的修改并不会引起dom节点的重新渲染...这也太坑爹了!后来想了个办法,给他加个wx:if就好了...

事件传参

写习惯vue的我上来就是bindtap="handleClick('我是参数')"(举例),到方法里面接受参数打印一看,卧槽...这是什么玩意,咋成了event对象了...一查才知道:小程序穿参需要在绑定事件的标签上手动设置参数,例如上面这个,应该这么写:data-abcd(参数名随意)="我是参数"

这里还有两个坑

“data-”后面应该是小写

不同单词之间用"-"隔开,小程序会将data-后面的部分自动转成小驼峰,而如果我们自己上来就写小驼峰,例如这样:data-dataType="json",小程序会将dataType转成datatype...因此找不到dataType这个参数...

target和currentTarget

由于小程序事件默认是会冒泡的,比如我们在大盒子上加了一个点击事件,表示这个区域点击触发一个函数,这个函数需要参数(从target.dataset里拿),而大盒子里有若干个小盒子,小盒子上没有加点击事件,大盒子上绑定的有参数,而小盒子上没有,当我们点击小盒子时,小程序会先执行该函数,但是由于他没有绑定参数,所以报错了...结论:targetcurrentTarget这两个都在event事件对象中,都是用来存储绑定数据的地方,但是target表示的是当前触发事件的对象,而currentTarget表示注册该事件的地方,所以我们应该用currentTarget来拿绑定的数据

顽强的按钮边框线

小程序有很多api都不是能够用代码来主动触发的,比如最常用的授权,除了用户第一次进入小程序可以使用代码来提示用户获取授权之外,其他时候都必须用button,用户主动点击该按钮才可以执行授权...言归正传,由于button按钮的不可替代,但是我们又需要修改他的button样式,所以问题来了,我发现button的边框线无法取消掉...无论我用border:none;还是border:0px;都无法取消掉边框线。半天之后才查到需要这样做:

button:after{
    border:none;
}

太坑了!你都没在文档说过!太过分了...

wxs

小程序的template局限性很大,没有办法使用methods渲染洗数据(例如plan="{{getPlan()}}"),为了实现这种效果,就需要用到了wxs了。 但是wxs的局限性也很大:

  • 不支持es6 wxs中不支持es6,这就导致很多写法都不能用,例如Array.forEachArray.map等数组方法都不能用,只能写原生的for循环。
  • 不支持Object对象 有时候想要遍历对象的key或者value,就需要用到Object对象(Object.keys()Object.values()),然后我就发现Object找不到(undefined),无语,那这咋整...后来我在网上查资料,神通广大的网友提供了以下函数:
// ! 尝试封装对象遍历
function each(obj, cb) {
   var str = JSON.stringify(obj)
   var reg = getRegExp('"(\w|-|_)+":', 'g')
   var matchArr = str.match(reg)
   if (matchArr) {
       for (var i = 0; i < matchArr.length; i++) {
           var objKey = matchArr[i]
           objKey = objKey.substring(1)
           objKey = objKey.replace('":', '')
           cb && cb(objKey, obj[objKey])
       }
   }
}
  • 不支持Date对象 通常想要获取时间格式,我们都是采用new Date(),使用Date对象,然后就和Object一样了,还好小程序给出了解决方案:getDate([时间戳/或者时间格式字符串])

自定义组件

小程序的自定义组件也有很多局限性,最大的一个问题在于,没用办法引入外部函数,例如:

// js文件A
function a(){}
function b(){}
module.exports = {
    a,b
}

这样的外部函数文件,自定义组件引入后我发现没办法使用,原因未知。 为了解决这个问题,我查了很多文档,最后才用了自定义组件的Behavior,相关文档: developers.weixin.qq.com/miniprogram…

这个确实解决了我的问题,但是Behavior只能被自定义组件使用,其他的js文件是没办法使用的,这就会导致我一个逻辑可能需要维护多份代码。后来我偶然间发现,定义为Class的js文件,居然可以使用!

// js文件B
class b {
  static a(){}
  static c(){}
}
export default Price;

这样自定义组件引入整个文件B(import B from 'B.js';)后,采用B.a()就可以使用对应函数了。

先写到这吧,后面遇到更多的坑再补....我需要冷静........