微信小程序问题记录

1,872 阅读5分钟

一、背景

前端第一次使用 Wepy 框架(Wepy 2) 开发小程序,把遇到的坑都罗列一遍,希望能给大家做个参考。

二、问题总结

1、this 和 事件对象(event)的指向
之所以提出这个问题是因为在我们遇到问题查阅资料时,把一些用原生或者其他框架写的代码应用到自己的代码中,如果出现问题,可以朝这个方向排查一下。

在 Wepy2 中,this.$wx 对应原生的 this,event.$wx 对应原生的 event。

2、代码上传到体验版请求头出现“Provisional headers are shown”
问题分析:在调试阶段和后端约定响应头增加字段“JWT-TOKEN”,字段名称变成了“jwt-token”导致字段值获取不到,接口没能正确返回。

解决方案:为了兼容调试和发布两种环境,把字段大小写两种情况都写一下,注意避免和其他字段冲突。

3、子组件传多个参数给父组件问题
问题分析:虽说 Wepy 是一款类似 Vue 语法的开发框架,但是在 Wepy2 中,子组件传多个参数给父组件时,父组件只能接收到最后一个参数,

解决方案:以对象的方式传给父组件

4、wx.getPhoneNumber() 接口在用户拒绝授权手机号返回的提示信息不同
iOS:'fail user deny'
Android: 'fail:user deny'

5、wx.getSystemInfo() 接口在 iPhone 11 系列手机上获取 model 信息有误("unknown<iPhone12,1>")
问题分析:目前苹果11上市后微信对苹果11还没有适配不能拿到 iPhone 11 标识

解决方案:通过判断“system”是“ios”且“model”为“unknown”来判断,也可以使用 “platform”,但是注意这个字段在微信开发者工具上是"devtools",需要多考虑一种情况,具体使用哪种可以根据实际情况来选择

接口在 iPhone 11 上的返回结果:



6、微信小程序自定义导航栏(navigationStyle: 'custom')
问题分析:微信开放了自定义导航栏的控制权,使得我们开发者可以自由的开发导航栏,但同时增加开发者们不得不兼容各种手机的负担。

解决方案:参考链接 需要注意对 iPhone 11 的兼容。

组件代码:如果需要可以直接 copy 到项目中使用(基于原生的项目需要稍作修改)。

<style lang="less">
  @import '~@/styles/mixin.less';
  .navbar {
    width: 100%;
    background-color: #fff;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 999;
  }
  .navbar-con {
    height: 40px;
    position: relative;
    .alignCenter;
  }
  .capsule {
    margin-left: 10px;
    height: 31px;
    background: rgba(255, 255, 255, .5);
    border: 1px solid rgba(151, 151, 151, 0.1);
    border-radius: 25px;
    .alignCenter;
    &.noBorder {
      border: none;
    }
    &__item {
      width: 43px;
      height: 34px;
      position: relative;
      .flexCenter;
      &:nth-child(2):after {
        content: '';
        position: absolute;
        top: 6.5px;
        left: 0;
        width: 1px;
        height: 17px;
        background: rgba(151, 151, 151, 0.1);
      }
      image {
        width: 17px;
        height: 17px;
      }
    }
  }
  .title {
    width: 50%;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    .flexCenter;
    .fontBasic(16px, #000);
  }
  .navBar-loader {
    height: 18px;
    width: 18px;
    animation: loader-1-1 4.8s linear infinite;
    display: inline-block;
    margin-right: 4px;
    vertical-align: middle;
  }
  @keyframes loader-1-1 {
    0% {
      transform: rotate(0deg);
    }
    100% {
      transform: rotate(360deg);
    }
  }
  .navBar-loader .inner {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    margin: auto;
    height: 18px;
    width: 18px;
    clip: rect(0, 18px, 18px, 9px);
    animation: loader-1-2 1.2s linear infinite;
  }
  @keyframes loader-1-2 {
    0% {
      transform: rotate(0deg);
    }
    100% {
      transform: rotate(220deg);
    }
  }
  .navBar-loader .inner:after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    margin: auto;
    height: 18px;
    width: 18px;
    clip: rect(0, 18px, 18px, 9px);
    border: 3px solid #ccc;
    border-radius: 50%;
    animation: loader-1-3 1.2s cubic-bezier(0.770, 0.000, 0.175, 1.000) infinite;
    z-index: 1000;
    box-sizing: border-box;
  }
  @keyframes loader-1-3 {
    0% {
      transform: rotate(-140deg);
    }
    50% {
      transform: rotate(-160deg);
    }
    100% {
      transform: rotate(140deg);
    }
  }
</style>

<template>
  <div class="container">
    <div class="navbar" style="height:{{systemInfo.navBarHeight}}px;background-color:{{bgColor}};">
      <div style="height:{{systemInfo.statusBarHeight}}px"></div>
      <div class="navbar-con" style="height:{{systemInfo.navBarHeight-systemInfo.statusBarHeight}}px">
        <div class="capsule" :class="{noBorder:!(back&&home)}" wx:if="{{ back || home }}">
          <div class="capsule__item" @tap="backstep" wx:if="{{back}}">
            <image src="@/images/back.png" mode="widthFix" />
          </div>
          <div class="capsule__item" @tap="backHome" wx:if="{{home}}">
            <image src="@/images/home.png" mode="widthFix" />
          </div>
        </div>
        <div class="title" style="color:{{fontColor}};">
          <div wx:if="{{loading}}" class="navBar-loader">
            <div class="inner"></div>
          </div>
          <text>{{title}}</text>
        </div>
      </div>
    </div>
    <div style="height:{{systemInfo.navBarHeight}}px;"></div>
  </div>
</template>

<script>
  import wepy from '@wepy/core'
  import store from '@/store'
  import {
    mapState
  } from '@wepy/x'
  wepy.component({
    store,
    props: {
      title: {
        type: String,
        default: 'AIDerma'
      },
      bgColor: {
        type: String,
        default: '#ffffff'
      },
      fontColor: {
        type: String,
        default: '#000000'
      },
      back: {
        type: Boolean,
        default: false
      },
      home: {
        type: Boolean,
        default: false
      },
      loading: {
        type: Boolean,
        default: false
      }
    },
    computed: {
      ...mapState(['systemInfo'])
    },
    methods: {
      backHome() {
        wx.reLaunch({
          url: '/pages/case/list'
        })
      },
      backstep() {
        wx.navigateBack({
          delta: 1
        })
      }
    }
  })
</script>


获取不同类型手机的自定义 navBar 高度:


wx.getSystemInfo({  success: (res) => {    let menuButtonInfo = wx.getMenuButtonBoundingClientRect() // 基础库 2.1.0 开始支持,低版本需做兼容处理。    let systemInfoObj = {      statusBarHeight: res.statusBarHeight,  // 时间、信号等工具栏的高度      windowHeight: res.windowHeight,  // 可使用窗口的高度      navBarHeight: 0,   // 自定义导航栏高度      contentHeight: 0   // 页面内容高度    }    systemInfoObj.navBarHeight = menuButtonInfo.bottom + menuButtonInfo.top - res.statusBarHeight    systemInfoObj.contentHeight = systemInfoObj.windowHeight - systemInfoObj.navBarHeight    if (res.screenHeight / res.screenWidth > 2) {      this.$options.store.commit('isIPXUpdate', true)    }    this.$options.store.commit('SystemInfoUpdate', systemInfoObj)  }})


7、小程序 wx.getSystemInfo 获取 windowHeight 问题
问题分析:在一些设备下获取 windowHeight 不能准确得到对应的高度,总是拿到屏幕高度,一般第一次杀掉微信进程后第一次打开会有这个问题,并且安卓设备上易现。

解决方案(参考链接):

windowHeight 的定义:可使用窗口高度,即:屏幕高度(screenHeight) - 导航(tabbar)高度;

可以看出这个值取决于 tabbar 是否存在,为了保证 tabbar 显示后再取值,建议在生命周期的 onReady 钩子中调用接口 wx.getSystemInfo,如果我们配置了自定义导航栏(navigationStyle: 'custom'),屏幕高度和窗口高度是相等的,我们可以直接使用屏幕高度

8、页面内跳转点击无反应
问题分析:通过打印“getCurrentPages()”到控制台,可以发现这是微信小程序路由跳转的一个隐藏的坑,就是 wx.navigateTo 打开新页面,最多只能打开 10 个,超过 10 个之后就没反应,控制台也不会报错。

解决方案:页面深度最好不要超过10层(如果有,可以适当使用 wx.redirectTo() 进行跳转),如果页面上有回到首页按钮,使用 wx.reLaunch() 进行跳转。

9、Echarts 在微信小程序中实践(基于 Wepy)
占位

10、一些建议
  • 由于小程序对代码包大小的限制(2M),建议把首屏图片放在本地其他都放在 CDN,必要时做一下图片的预加载。
  •  建议还是一开始就做好分包准备