回复 刷新

暂无评论

微信小程序踩坑资料整理

申明:本文纯属资料整理,如有违规请评论联系作者删除。

1. navigator点击出现阴影,如何去除阴影

做法:将navigator组件的hover-class设置为none:hover-class=“none”

<navigator url='index' class="nav" hover-class='none'> ..... navigator>

2. 页面可以左右滑动且出现白色部分

做法:因为页面有元素总宽度超出 750rpx,所以导致页面可以左右滑动且出现白色部分。需要检查好样式,找出超过750rpx的原因,进行修改。

3. 如何进行针对某个页面的下拉刷新:enablePullDownRefresh:true

在小程序的 app.json 中配置 window 项的enablePullDownRefresh为true,小程序的所有页面都可以下拉刷新

如果只要某个页面可以下拉刷新,只要配置这个页面的config项enablePullDownRefresh:true即可。

同时配置 backgroundTextStyle: “dark”,实现下拉刷新的点是黑色的

config = { navigationBarTitleText: '....', enablePullDownRefresh:true, backgroundTextStyle: "dark" }

监听页面的下拉刷新事件

onPullDownRefresh(){ .... this.loadOrderList(1,true); //做一些异步请求,更新页面数据 .... } async loadOrderList(page,pullrefresh){ let result = await getOrderList(page); ..... if (pullrefresh) { // 异步请求函数内写明,如果该函数是通过下拉刷新触发的,请求结束后,需要关闭下拉刷新的动画效果 wx.stopPullDownRefresh(); } this.$apply(); }

4. 如何禁止组件swiper手动滑动

有时候因为需求,不希望用户可以手动滑动swiper-item

<swiper autoplay="true" circular="true" duration="2000" interval="7000" vertical="true" catchtouchmove='catchTouchMove'> <swiper-item wx:for-items="{{list}}" wx:for-index="index" wx:key="index" catchtouchmove='catchTouchMove'> .... swiper-item> swiper> methods = { catchTouchMove(e){ return false; } }

5. 去除button按钮的默认边框线

小程序就是这么神奇,直接 border:none 是没有办法去除按钮的边框线的。得这样写:

button::after{ border: none; }

6. 增加按钮的点击反馈效果

  1. wx.vibrateLong():使手机发生较短时间的振动(400ms)
  2. wx.vibrateShort():使手机发生较短时间的振动(15ms), 但是该效果只支持iPhone7及以上机型以及少部分安卓机型
bindtap(){ wx.vibrateShort(); }

7. 优化输入为空时候的提示:利用input的属性placeholder-class

<input placeholder-class="{{isNull?'color-red':''}}"/> .color-red{ color:red; } testIsNull(val){ if(val==''){ this.isNull = true; this.$apply(); } }

8.chooseLocation无反应

存在一种情况,就是当首次申请授权使用用户地理位置时被拒绝,接下来每次点击chooseLocation都会没有反应。因为授权被拒后,都不会再弹出授权弹框了。授权弹框只弹一次,所以必须考虑授权被拒的处理情况。授权被拒,只能打开设置页面,让用户手动授权。

一般我们在onLoad页面的时候就申请授权

当使用chooseLocation的时候需要进行fail处理

wx.chooseLocation({ success:function(res){ ...//成功 }, fail:function(){ ...//失败 this.authorizationAgain(); // 提醒用户再次授权 } }); authorizationAgain(){ wx.getSetting({ success:function(res) { if (!res.authSetting['scope.userLocation']) { console.log('已经拒绝过授权'); wx.showToast({ title:'您已经拒绝过使用地理位置授权请求,请前往设置开启授权', icon:'none' }) setTimeout(function(){ wx.openSetting({ success (res) { console.log(res.authSetting) } }) },1500) } } }) }

9.input组件opacity设置为0,无效



就是这么神奇,微信开发者工具一切正常,但是真机测试 opacity:0 根本不起作用。这是小程序官方组件的bug。当inpu focus时 opacity:0就失效了。blur时又生效了。

所以要实现input隐藏的功能还不能使用opacity,得考虑其他途径。

我是通过设置padding-left当它变得很大,内容被挤掉达到隐藏的效果。可以看到绿色那一块就是padding-left,

.input{ position: absolute; top: 0; left: 0; height:80rpx; font-size: 1rpx; color:gray; letter-spacing: 880rpx; opacity: 0; overflow: hidden; padding-left:600rpx; } <view class="mask" wx:if='{{showPayModal}}' > <view class="modal col"> <icon class='close' type="clear" size="26" bindtap='clickCloseMask'/> <view class="title">输入支付码view> <view class="col input-panel " bindtap='inputpay'> <view class="rect row"> <text class="fang row">{{paycodeText[0]}}text> <text class="fang row">{{paycodeText[1]}}text> <text class="fang row">{{paycodeText[2]}}text> <text class="fang row">{{paycodeText[3]}}text> <text class="fang row">{{paycodeText[4]}}text> <text class="fang row">{{paycodeText[5]}}text> view> <input bindinput='bindinput' class='input' type='number' password='true' maxlength='6' focus="{{focus}}"/> view> view> view> .mask{ width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); position: fixed; z-index: 99; .modal{ position: fixed; top: 42%; left: 50%; background: #fff; width: 630rpx; height: 342rpx; border-radius: 8rpx; transform: translate(-50%,-50%); } .input-panel{ justify-content: center; position: relative; margin-left: 12rpx; } .rect{ /* margin-left: -12rpx; */ } .title{ font-size: 36rpx; margin-top: 70rpx;margin-bottom: 60rpx; font-weight: bold; } .close{ position: absolute; top: 20rpx; right: 20rpx; } .input{ position: absolute; top: 0; left: 0; height:80rpx; /* border: 1rpx solid red; */ font-size: 1rpx; color:gray; letter-spacing: 880rpx; opacity: 0; overflow: hidden; padding-left:600rpx; } .fang{ width: 80rpx; height: 80rpx; border: 1rpx solid #ddd; margin-right: 12rpx; justify-content: center; font-size: 36rpx; color: #888; } }

10. chooseLocation API设计超级不合理而且返回结果极其随意

chooseLocation返回数据的关键字段分别是address:用来描述省市区街道,name:用来描述具体某个建筑物。当我们点击某一列数据时,拿到的返回结果就是如上描述。从省市区街道建筑物,该有的数据都有,而且排列整齐,符合预期结果。

但是,如果用户只是通过移动地图上的点,移动完后看下列默认选择的第一列数据刚好符合预期,直接点了确定,拿到的 address = name(基本相等,并不完全相等,是不是完全相等还是看缘分的) 其字符串组成大致为 “建筑物(市区街道)”。

为什么说大致,这恰恰是我想吐槽的返回数据的随意性!取到什么数据完全看缘分!()里可能有市也可能没有,可能有区街道描述,也可能没有。不信的小伙伴多划拉几下测试几遍你就知道了!!!!

这两种情况取到的数据有一个poiid可以区分。当我们默认选择第一项数据时,poiid为‘City’,可以看到address与name基本相等。当通过点击除第一项数据以外的数据,poiid是一个具体的qqmap_id,address刚好描述其具置,name刚好是建筑物的名称。

对于地址表设计谨慎精确的来说,这简直是烂到爆的API。没有分割省市区街道,返回数据有没有省市区全看缘分。这时候还是需要引入第三方地图。怕其他地图产品跟微信小程序地图产生结果会有细小的差别,只能选择跟微信小程序出自同一个爸爸的腾讯地图。

通过chooseLocation拿到经纬度,再通过腾讯地图进行逆地址解析,取得province/city/district/street三个值。

具体教程查看 API 文档 https://lbs.qq.com/qqmap_wx_jssdk/method-reverseGeocoder.html

其返回结果res.data.result.address_component含有nation(国家)/province(省)/city(市)/district(区)/street(街)这是可以取用的数据。

但是formatted_addresses描述的数据会跟小程序chooseLocation显示给用户的数据有细小的差别,其描述的建筑物不一定是chooseLocation默认第一项描述的建筑物,所以这一部分数据不能取用。所以我们需要“湖景1号”的数据只能通过js截取字符串去截取

selectLocation(){ let that = this; wx.chooseLocation({ success:function(res){ console.log(res); that.form.longitude = res.longitude; that.form.latitude = res.latitude; let ischoose = res.poiid=='City'; that.form.street = res.address; that.form.desc = res.name; if (ischoose) { that.form.desc = res.name.substring(0,res.name.lastIndexOf('(')); } that.$apply(); that.loadCity(res.longitude,res.latitude,ischoose); //省市区 console.log('chooseLocation',res); }, fail:function(){ that.authorizationAgain(); } }); } loadCity(longitude,latitude,flag){ var that = this; wx.request({ url: 'https://apis.map.qq.com/ws/geocoder/v1/?location=' + `${latitude},${longitude}&key=腾讯地图Key`, success(res) { let info = res.data.result; console.log(info); let pro = info.address_component; that.form.province = pro.province; that.form.city = pro.city; that.form.district = pro.district; if (flag) { that.form.street = info.address; } that.$apply(); } })

11.数据绑定 Mustache 语法(双大括号)

这个 {{}} 里面不能执行任何的方法,只能做简单的四则运算和Boolen判断,比如:

{{parseInt(i)}}

你这么干是不行的,你只能在拿到数据的时候就先对数据格式化一遍。

但是你如果非要在渲染的时候再格式化的话也行,你就只能通过WXS来处理了,比如:

var parse = function(str) { return parseInt(str); }; module.exports.parse = parse; {{m1.parse(i)}}

12. wx.navigateBack() 无法向回退的页面传参

小程序的几个导航api,都可以通过 url 给对应的页面传参。而 w x.navigateBack({delta}), 只接受一个delta(返回的页面数)参数。但是有时候确确实实有向回退页面传参数的情况,这时候就只能通过localstorage或是redux等来处理了。

13. rpx 单位适配问题

小程序提供的 rpx 单位确实让我们开发的时候在高精度还原设计稿上省了很多事情。但是小记发现当你使用1rpx在一些机型上特别容易出问题。

.border { border: 1rpx solid #000; }

如果你这样设置边框的时候,大多数情况下它都能正常显示,但是在一些机器上尤其是 iPhone X 边框有时候根本不显示。所以我现在都改成 2rpx

14. 绑定事件获取的target与currentTarget是有区别的

在绑定事件获取当前组件数据的时候,拿到的event里面有target和currentTarget 这两个玩意儿里面都有一个dataset,而我们需要获取的数据就在dataset对象里面。正确的我们应该取 currentTarget 里面的就行,但是有时候这两个的数据是完全一样的,一不小心你就取错了。

那这个 target 和 currentTarget 有什么区别呢,官方的解释:

  1. target:触发事件的源组件;
  2. currentTarget: 事件绑定的当前组件;

看个例子:

<view id="outer" bindtap="handleTap1"> outer view <view id="middle" catchtap="handleTap2"> middle view <view id="inner" bindtap="handleTap3"> inner view view> view> view>

点击 inner view 时,handleTap3 收到的事件对象 target 和 currentTarget 都是 inner,而
handleTap2 收到的事件对象 target 就是 inner,currentTarget 就是 middle。

其实很容易区分,target就是事件开始的地方,currentTarget就是你绑定事件的地方。

15. CSS引用静态资源问题

iconfont, 图片不能通过css,哦~应该该叫 wxss 本地引入。

  1. iconfont @font-face 引用的ttf等文件在小程序中不支持,可以使用线上或转base64。
  2. 图片可以使用base64或者线上链接。或者哦,对了图片链接一定要带 https 协议头

16.view 添加点击效果

需要主动开启

17. page wxss样式层级

下面是一个page 示例:

<view class="page-layout"> <view class="page__title">flex-direction: rowview> <view class="flex-wrp" style="flex-direction:row;"> <view class="flex-item green">1view> <view class="flex-item red">2view> <view class="flex-item blue">3view> view> view> /* wxss */ .page-layout { color: #000; }

/* 下面这种写法 .red 是不生效的 */

.red { color: #f00; }

/* 必须这么写 */

.page-layout .red { color: #f00; }

18. 其他注意点

  1. 任何情况下的视图更新只能通过setData()
  2. 路径只能是五层,请尽量避免多层级的交互方式。
  3. 不要直接对 Page.data进行修改,请使用 Page.setData
  4. 跳转到tabbar页面一定要用 wx.switchTab()
  5. 使用wx:for遍历的时候最好加上wx:key=”{{index}}”
  • 127
  • 0
  • 0