微信小程序开发遇到的各种问题一

4,001 阅读5分钟

这篇目主要为记录开发小程序时遇到的各种问题

1.navigateto跳转栈溢出

navigateTo会有栈内存溢出的问题,因此需要做一个判断,最大栈内存是10层

  switchTab(e) {
            const data = e.currentTarget.dataset
            const url = data.path
            // console.log(url)
            // //切换tab时,改变路由地址
            if (getCurrentPages().length <= 0) {
                wx.navigateTo({
                    url
                })
            } else {
                wx.reLaunch({
                    url
                })
            }
           //这里可以得到栈的层数
            console.log('栈', getCurrentPages().length)
            this.setData({
                //切换tab时,改变当前激活的序号,改变tab颜色图标等样式  
                selected: data.index
            })
        }

2.数据库无法接受表情字符

当我们在小程序的表单中提交表情时,这是数据库如果不加处理,是无法接受的,因此需要字符串转码

2.1 提交表单

提交表单转码,接受数据在转回来

通过encodeURI解码方式
let regex = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig
//利用正则替换
    let nickWords = this.data.words.replace(regex, function (res) {
      return encodeURIComponent(res)
    })
    let nickTitle = this.data.title.replace(regex, function (res) {
      return encodeURIComponent(res)
    })
    let nickTopic = this.data.topic.replace(regex, function (res) {
      return encodeURIComponent(res)
    })
    let params = {
      contract_id: parseInt(this.data.initList.contract_id),
      works: nickWords,
      title: nickTitle,
      topic: nickTopic,
      picture_urls: this.data.picArr,
      video_urls: this.data.vedioArr
    }

2.2接受数据

         topic: decodeURIComponent(res.result.topic),
          //标题
          title: decodeURIComponent(res.result.title),
          //内容文字
          words: decodeURIComponent(res.result.works)

这里有个问题这种udcode编码方式,存在%问题,因此在提交时需要转义一下%,万一用户输入表情加%又会出现问题,如果文字输入中原本就存在%,在转码时会将%转码,因此需要用正则将%换成%25,在解码过后%25自动会转成%。

 analysisEmoji(str) {
   //将%转成%25
    let keyStr = str.replace(/%/g, "%25")
    let regex = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig
    let nickWords = keyStr.replace(regex, function (res) {
      return encodeURIComponent(res)
    })
    return nickWords
  },
    

3.真机MiniProgramError报错

信真机调试时出现: (in promise) MiniProgramError {“errMsg“:“hideLoading:fail:toast can‘t be found“} Object

wx.showLoading 和 wx.showToast 同时只能显示一个

wx.showLoading 应与 wx.hideLoading 配对使用 解决方法

定义一个变量isShowLoading=false;

调用 wx.showLoading 时候赋值 isShowLoading为true,并调用showLoading

     if(!isShowLoading){
        wx.showLoading({
          title: '加载中',
          icon: 'loading',
        })
        isShowLoading =true;
      }
//调用 wx.hideLoading 时候先判断 isShowloading,为true才能执行,否则不执行。
    if(isShowLoading){
      wx.hideLoading()
      isShowLoading =false;

}
//调用 wx.showToast 时候判断 isShowloading,为true就执行 wx.hideLoading ,
//否则不执行。接着执行showToast函数。
      if(this.data.isShowLoading){
        wx.hideLoading()
      }
      wx.showToast({ 
        title: '没有更多数据了',
        icon: 'none',

      });

4.swiper设置圆角时,瞬间直角问题

当设置swiper圆角时,会出现先直角后圆角

解决方式:
1.需要在swiper外面的盒子设置  overflow: hidden;
2.在swiper上设置
ovewflow:hidden;
border-radius:10rpx;
transform: translateY(0);
3.给图片设置圆角
border-radius:10rpx;
   <view class="swiper_content">
                <swiper autoplay interval="2000" circular indicator-dots indicator-color="rgba(44,44,44,.3)" indicator-active-color="rgba(255,128,64,.9)" style='ovewflow:hidden;border-radius:10rpx;transform: translateY(0);'>
                    <swiper-item class="" item-id="">
                        <image class="" src="../../images/swiper/01.png"></image>
                    </swiper-item>
                    <swiper-item class="" item-id="">
                        <image class="" src="../../images/swiper/02.png"></image>
                    </swiper-item>
                    <swiper-item class="" item-id="">
                        <image class="" src="../../images/swiper/03.png"></image>
                    </swiper-item>
                    <swiper-item class="" item-id="">
                        <image class="" src="../../images/swiper/04.png"></image>
                    </swiper-item>
                    <swiper-item class="" item-id="">
                        <image class="" src="../../images/swiper/05.png"></image>
                    </swiper-item>
                    <swiper-item class="" item-id="">
                        <image class="" src="../../images/swiper/06.png"></image>
                    </swiper-item>
                </swiper>
            </view>
   .swiper_content {
            width: 710rpx;
            height: 250rpx;
            position: absolute;
            left: 50%;
            transform: translateX(-50%);
            top: 20rpx;
            border-radius: 10rpx !important;
            border-radius: 30rpx;
            overflow: hidden;
            swiper {
                width: 100% !important;
                height: 250rpx !important;
                border-radius: 10rpx !important;
            }

            swiper-item {
                width: 100%;
                border-radius: 10rpx !important;
                position: relative;
            }

            image {
                width: 100%;
                height: 250rpx;
                border-radius: 10rpx;


            }
        }

5.scroll-view横向滑动存在拉动条问题

使用scroll-view时需要隐藏滚动条,默认是存在滚动条

 //在父盒子中加上
     ::-webkit-scrollbar {
            width: 0;
            height: 0;
            color: transparent;
        }

6.自定义导航栏

在实际需求中,小程序的默认导航栏需要变成我们想要的模式,例如,搜索,滑动等,实际上就是先去除默认的导航条,在根据小程序提供的接口计算进行导航条位于顶部的高度,

导航栏由三部分组成,胶囊,最顶部导航栏,主体导航栏

6.1配置index.json,隐藏原始导航栏

  "navigationStyle":"custom"

6.2 计算最顶部导航栏高度

//index.js
 wx.getSystemInfo({
      success: (res) => {
        this.setData({
          statusBarHeight: res.statusBarHeight,
        });
      },
    });
//index.wxml
<view  style="width:100%;height:{{statusBarHeight}}px;background-color:#88D0FF">
</view>

6.3 根据导航栏与胶囊计算主体导航栏高度

//index.js
let systemInfo = wx.getSystemInfoSync();
    let rect = wx.getMenuButtonBoundingClientRect
      ? wx.getMenuButtonBoundingClientRect()
      : null; //胶囊按钮位置信息
    wx.getMenuButtonBoundingClientRect();
    let navBarHeight = (function () {
      //导航栏高度
      let gap = rect.top - systemInfo.statusBarHeight; //动态计算每台手机状态栏到胶囊按钮间距
      return 2 * gap + rect.height;
    })();
    this.setData({
      navBarHeight
    });
//index.less
.nav_title_area{
         position: relative;
         color: #fff;
        .select_option{
            display: flex;
            align-items: center;
            height: 100%;
            vertical-align:middle;
          text{
            padding-left: 20rpx;
            padding-right: 5rpx;
            padding-bottom: 5rpx;
          }
         
        }
        .nav_title{
          position: absolute;
          top:50%;
          left: 50%;
          transform: translate(-50%,-50%);
          color: #fff;
        }
    }

6.4 需要将导航栏固定定位

  //index.wxml
<view style=' position: fixed; top: 0px;left:0px; width:100%;height:{{statusBarHeight+navBarHeight}}px;z-index:999'>
        <view style="width:100%;height:{{statusBarHeight}}px;background-color:#88D0FF" class='statusBarHeight'></view>
        <view class="nav_title_area" style="width:100%;height:{{navBarHeight}}px;background-color:#88D0FF">
            <view class="select_option">
                <picker range="{{citySelect}}" value="{{citySelectIndex}}" bindchange="bindcityPickerChange" class="pickCity">
                    <text>{{citySelect[citySelectIndex]}}</text>
                    <van-icon name="arrow-down" size="14px" />
                </picker>
            </view>
            <view class="nav_title">商单广场</view>
        </view>
    </view>

6.5 需要增加一个view填补导航栏固定定位留下的空白

 <view style="width:100%;height:{{statusBarHeight+navBarHeight}}px"></view>

7.扫小程序码进入详情页参数无法获取

扫小程序码进入一个固定页面,这个很简单,直接在开发者后台生成就可以,但是如果需要动态生成,根据不同的详情页id生成不同的小程序码,这个时候因为是直接进入该页面,不经过首页,因此在onLoad中的options是拿不到这个id的,这是需要另外一个参数scene

 onLoad: function (options) {
if (options.aId) {
      this.setData({
        aId: options.aId,
      });
    } else if (options.scene) {
      //这里需要解码
      let scene = decodeURIComponent(options.scene);
      let aId = parseInt(scene.split("=")[1]);
      this.setData({
        aId: aId,
      });
    } else {
      this.setData({
        aId: this.data.aId,
      });
    }
}
我传递过来的应该是/pages/details/index?aId=2196,scene得到?后面的部分
解决办法是在scene中获取这个参数,是?后面的部分,获取的参数是aId%3D2196,需要通过
decodeURIComponent解码aId=2196
 let scene = decodeURIComponent(options.scene);
使用正则或者字符串切割的方式得到aId

这里很难进行调试,需要根据微信开发者工具进行调试,跟换编译模式

image.png

调试的时候可以选择编译模式1047,scene后面的可以根据
    let a='aid=1234'
   var uri_encode=encodeURIComponent(a);
   console.log(uri_encode);
   反编码得到

8.根据经纬度得出对应地点

这里结合腾讯地图进行操作,通过小程序的经纬度结合腾讯地图api,实现获取当前城市位置

8.1 在后台管理系统配置腾讯地图插件

设置=>第三方设置=>添加插件

8.2.申请腾讯地图账号,生成key

WebServiceAPI需要配置,域名白名单,填写servicewechat.com,这个一定要写,并填写微信小程序appid image.png

8.3.在app.json中配置

目的是可以调用小程序的api获取当前地点的经纬度

 "permission": {
    "scope.userLocation": {
      "desc": "你的位置信息将用于小程序定位"
    }
  },

8.4.使用qqmap-wx-jssdk

引入qqmap-wx-jssdk

import qqmapwx from "../../utils/qqmap-wx-jssdk.min.js";
Page({
  /**
   * 页面的初始数据
   */
  data: {},

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    const qqmapsdk = new qqmapwx({
      // 使用你在腾讯地图应用生成的key
      key: "LM5BZ-F55W3-X3J3R-YXUVL-LCF7V-DZBBW",
    });
    // 小程序会弹窗提示授权后才会执行
    wx.getLocation({
      type: "wgs84",
      success(res) {
        //得到经纬度
        console.log(res);
        qqmapsdk.reverseGeocoder({
          location: {
            latitude: res.latitude,
            longitude: res.longitude,
          },
          //成功后的回调
          success: (r) => {
            console.log("地址信息", r.result.address_component);
          },
          fail: function (res) {
            console.log(res);
          },
        });
      },
    });
  },

  
});

image.png