这篇目主要为记录开发小程序时遇到的各种问题
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
这里很难进行调试,需要根据微信开发者工具进行调试,跟换编译模式
调试的时候可以选择编译模式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
8.3.在app.json中配置
目的是可以调用小程序的api获取当前地点的经纬度
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于小程序定位"
}
},
8.4.使用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);
},
});
},
});
},
});