小程序

微信小程序踩坑资料整理

2018-10-31  本文已影响236人  VioletJack

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

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. IOS系统与Android系统Date数据类型比较不兼容

https://blog.csdn.net/qq_30604453/article/details/82021634

6. position:absolute布局IOS系统与Android系统不兼容

https://blog.csdn.net/qq_30604453/article/details/82116427

7. 如何解决map组件设置z-index无效

https://blog.csdn.net/qq_30604453/article/details/81670740

8. 改变数据然后通过$apply更新到视图层(用到wepy框架)微信开发者工具正常,但是真机测试视图层数据却无更新

https://blog.csdn.net/qq_30604453/article/details/81670509

9. wepy:官方demo报错 pages/index.js 出现脚本错误或者未正确调用 Page()

https://blog.csdn.net/qq_30604453/article/details/80968909

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

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

button::after{
  border: none;
}

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

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

bindtap(){
  wx.vibrateShort();
}

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

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

13.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)
          }
        }
      })
    }

14.### 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;
      }
    }

15. 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();
          }
      })

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

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

<view wx:for="{{['1.22', '2.22', '3.222']}}" wx:for-item="i">
  {{parseInt(i)}}
</view>

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

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

<wxs module="m1">
    var parse = function(str) {
        return parseInt(str);
    };
    module.exports.parse = parse;
</wxs>

<view wx:for="{{['1.22', '2.22', '3.222']}}" wx:for-item="i">
  {{m1.parse(i)}}
</view>

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

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

18. rpx 单位适配问题

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

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

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

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

在绑定事件获取当前组件数据的时候,拿到的event里面有target和currentTarget 这两个玩意儿里面都有一个dataset,而我们需要获取的数据就在dataset对象里面。正确的我们应该取 currentTarget 里面的就行,但是有时候这两个的数据是完全一样的,一不小心你就取错了。
那这个 target 和 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就是你绑定事件的地方。可以去看看小程序事件

20. CSS引用静态资源问题

iconfont, 图片不能通过css,哦~应该该叫 wxss 本地引入。
1、iconfont @font-face 引用的ttf等文件在小程序中不支持,可以使用线上或转base64 参考 微信小程序wxss样式文件中引用iconfont素材
2、图片可以使用base64或者线上链接。或者<image>哦,对了图片链接一定要带 https 协议头,形如://cdn.xxx.com/jflkadsjf.png 是不行的

21. view 添加点击效果

需要主动开启

<view hover hover-class="view-hover">

22. page wxss样式层级

下面是一个page 示例:

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

/* 下面这种写法 .red 是不生效的 */
.red {
    color: #f00;
}

/* 必须这么写 */
.page-layout .red {
    color: #f00;
}

23. 其他注意点

七牛云存储整理的小程序坑

<view hover hover-class="item-hover">

    url: url,
    data: data,
    method: "POST",
    dataType: "json",
    header: {
      'content-type': 'application/x-www-form-urlencoded' //==> 此处若为application/json则服务端无法获取POST的参数
    }

error

参考资料

上一篇 下一篇

猜你喜欢

热点阅读