微信小程序爬坑记录

开发微信小程序近两个月的小白,简单记录一下记忆比较深刻的坑

一 固定定位fixed

scroll-view下不能通过fixed进行固定定位,无法到达页面底部,使用view即可。

二 canvas

业务中需要实现这样一个效果

image

vantWeapp 中有一个Circle 环形进度条的组件


image

大家需要注意的是size默认单位为px 而不是rpx 也就是说不可以自适应 需要通过 wx.getSystemInfoSync().windowWidth获取设备宽度后根据当前宽度得出一个系数实现自适应 另外canvas 标签默认宽度300px、高度150px。

三 lottie-miniprogram

这绝对是一个大坑,微信小程序对lottie的兼容性真的很差,真机调试情况下无法获取canvas,会报错,只能通过预览去看效果,这就给调试带来了困难。
但这只是开始,
image

需要注意的是在组件中获取canvas需要加上in(this) 要不然无法获取到canvas节点


image
本来以为这样就结束了,但现实很残酷,第一次进入页面渲染正常,但是再次进入页面,动画就不动了,然后去社区发现了很多类似的情况,应该是官方的bug,看到github上有人提出通过destory方法在退出页面时进行销毁就可以解决这个问题,但遗憾的是这个destory方法并未被官方采纳。于是又到处去搬砖(参考:https://developers.weixin.qq.com/community/develop/doc/000c6c7330ce30571a1a4537556c00?highLine=lottie

略加修改后如下:

let frameFn = function () {};
let rid = 0;
let canvasDom = null;

 wx.createSelectorQuery()
      .select("#canvas")
      .node((res) => {
        const canvas = res.node;
        const requestAnimationFrame = canvas.requestAnimationFrame;
        canvas.requestAnimationFrame = function () {
          console.log("句子评测中的动画");
          frameFn = arguments[0];
          rid = requestAnimationFrame.apply(canvas, arguments);
          return rid;
        };
        // 页面第二次打开时动画默认不会开始,这里需要手动调用一次动画
        canvas.requestAnimationFrame(frameFn);
        canvasDom = canvas;
        lottie.setup(canvas);
        lottie.loadAnimation({
          autoplay: true,
          loop: true,
          path: PUBLIC_RES + "data.json", //lottie json包的网络链接
          rendererSettings: {
            context: canvas._ctx,
          },
        });
      })
      .exec();
      
    onUnload: function () {
        canvasDom.cancelAnimationFrame(rid);
这样总能解决了吧,可是又出现了新的问题,小程序中有两个地方使用到了动画,单个页面多次进入渲染没有问题,但是如果A页面正常,切换到B页面,那B页面就又不动了,两个页面只有一个页面的动画正常,然后又去爬坑,这次,你猜怎么着,没爬出来果断放弃,一个页面仍然使用lottie-miniprogram,另一个页面直接用gif动画,嗯,真香
还有就是canvas不能直接用wx:if进行显示隐藏,获取不到节点会报错,可以考虑采用定位left:1000rpx实现
.canvas {
  position: absolute;
  bottom: 190rpx;
  z-index: 100;
  width: 226rpx;
  height: 114rpx;
  left: 10000rpx;
  &.show {
    left: 261rpx;
  }
}

四 获取用户信息

获取用户昵称时,用到了wx.getUserInfo,但这个API需要用户授权,尝试用wx.authorize
拉取授权,但失败了,返回12007错误,好像这个API废弃了,必去通过button的开发能力拉取授权

<button wx:if="{{flag}}" class="login-btn" type="primary" open-type="getUserInfo" bindgetuserinfo="getUserInfo">
        授权用户信息
      </button>

五 关于云知声(语音评测API)

之前小程序保存用户录音用的是微信临时文件 tempFilePath,但只能保存三天,通过云知声url拼接的路径可以实现三个月的保存,但是需要获取header,尝试去监听第三方接口的请求头,但是没成功,后来发现可以直接在云知声返回的结果中拿到

export function hivoiceHttp({ recordPath, voiceData = {} }) {
  wx.showLoading({
    title: "评测中",
    mask: true, 
  });
  return new Promise((reslove, reject) => {
    wx.uploadFile({
      url: HIVOICE_BASEURL_HTTP,
      header: {
        "session-id": "uuid-t" + Date.now(),
        appkey: "",
        "score-coefficient": HIVOICE_LEVEL,
      },
      filePath: recordPath,
      name: "voice",
      formData: {
        ...voiceData,
      },
      // 在这可以拿到请求头
      success(res) {
        // 拿到header中的Session-Id并进行拼接
        let headerArr = res.header["Session-Id"].split(":");
        let myVoiceUrl = `https://edu.hivoice.cn/WebAudio-1.0-SNAPSHOT/audio/play/${headerArr[2]}/${headerArr[1]}/${headerArr[0]}`;
        console.log(myVoiceUrl, "=三个月=");
        wx.hideLoading();
        let data = res.data || "{}";
        // // console.log('uploadFile', data, voiceData)
        if (res.statusCode === 200) {
          if (typeof data === "string") {
            data = JSON.parse(data);
          }
          // 音质检测
          if (data.audioCheck) {
            let flag = false;
            const audioCheck = data.audioCheck;
          }
          data.myVoiceUrl = myVoiceUrl;
          reslove(data);
        } else {
          // console.log('uploadFile-succ-statusCode', res.statusCode)
          reject({ message: "非预期结果", res: data });
        }
      },
      fail(err) {
        wx.hideLoading();
        reject(err);
      },
    });
  });
}

六 引导层相关

坑一

image

灰色引导层采用固定定位,在ios下进行下拉刷新的时候,仍然置顶,但是在安卓下则会随着下拉刷新一起下来,找了一下,好像是官方的bug,需要手写一个下拉刷新的方法。

坑二

image

在做这个引导栏的时候,遮罩无法覆盖tabbar,有两种解决方案,一种是自己重写tabbar,但是可能兼容性不好,另一种也就是我才采用的方法,效果一般,仅供参考
我是先切一张tabbar的图片,在进入页面时先将tabbar隐藏,通过回调在隐藏结束后显示页面,同时显示定位到原来tabbar位置的切图,作为第二层,然后这时遮罩就可以进行覆盖了。

 wx.hideTabBar({
          success: () => {
            this.setData({ firstLogoin: true, tabbarFlag: true });// firstLogoin为整个页面显示状态位,tabbarFlag为tabber状态位
          },
        });

七 SwipeCell 滑动单元格

image

这个组件直接引用后删除是没有样式的,需要手动添加一个样式

.van-swipe-cell__right {
  display: inline-block;
  width: 65px;
  height: 44px;
  font-size: 15px;
  line-height: 44px;
  color: #fff;
  text-align: center;
  background-color: #EC714F;
}

需求中要求一次只能进行一次删除,因而一条右滑删除打开,另一条右滑删除就需要自动闭合,这就需要open事件,但是重点是通过bind:open="onOpen"绑定,居然不触发,需要修改源码,通过triggerEvent进行触发

image

然后就可以触发了,如果不是当前打开的列表项,就通过selectComponent调用close()方法即可,代码已贴

 <van-swipe-cell class="{{'van-swipe' + index}}" right-width="{{ 65 }}" wx:for="{{errorList}}" id="{{index}}" data-index="{{index}}" wx:key="{{index}}" async-close bind:open="onOpen" bind:close="onClose">
onOpen(event) {
    const { position, name } = event.detail;
    const { index } = event.currentTarget.dataset;

    this.data.errorList.forEach((error, errorIndex) => {
      if (errorIndex !== index)
        this.selectComponent(".van-swipe" + errorIndex).close();
    });
  },

八 关于分享

想要让一个页面可以分享,调用onShareAppMessage就可以了,但是同一个页面通过不同页面跳转过来,需要根据跳转的来源判断是否可以进行分享,可以通过hideShareMenu来实现

if (...) {
      wx.hideShareMenu({
        menus: ["shareAppMessage", "shareTimeline"],
      });
    }

如果分享出去的页面需要调用接口进行页面的渲染,可以将登陆后置,放开当前接口的鉴权,涉及到鉴权的操作时再弹出登录提示即可。

九 IOS字体适配

诸如fish中i在ios下面i不显示.且会和f连在一起,所以需要更改字体为:
font-family: Helvetica Neue;

十 视频播放完返回按钮异常

image

视频播放完成后中间的暂停按钮层级高于左侧返回按钮,导致返回按钮失效,可以去掉中间的结束按钮

show-center-play-btn="{{false}}"

十一 音频播放

const back = wx.getBackgroundAudioManager()

播放背景音乐时,发现音频没有及时更新,加上时间戳后正常

back.src = `${src}?t=${Date.now()}`;

还需要注意的是 createInnerAudioContext 可以播放微信临时文件,getBackgroundAudioManager 不支持

十二 自定义微信小程序tabbar上边框的颜色

两个小程序项目均提到原生tabbar颜色较深的问题,但是

image

所以只能自己模拟

在app.less中,通过伪类添加tabbar上边框定位下去
page::after {
  content: '';
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2rpx;
  background-color: #eeeeee;
  z-index: 9999;
}
在app.json中将tabbar颜色设为白色
 "tabBar": {
    "borderStyle": "white",
  },
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容