微信小程序的开发踩坑

前言

记录一下在开发小程序的时候遇到的问题,笔记跟坑我都稍微写一点

关于开发的

一. 生命周期和路由跳转

实在记不住( = = ||),但是用到的几率挺高,所以就索性抄下来了

1.页面的生命周期

  • onLoad—-监听页面加载
  • onReady—-监听页面初次渲染完成
  • onShow—-监听页面显示
  • onHide—-监听页面隐藏
  • onUnload—-监听页面卸载

2.组件的生命周期

  • created 组件实例化,但节点树还未导入,因此这时不能用setData
  • attached 节点树完成,可以用setData渲染节点,但无法操作节点
  • ready 组件布局完成,这时可以获取节点信息,也可以操作节点
  • moved 组件实例被移动到树的另一个位置
  • detached 组件实例从节点树中移除

3.路由跳转

直接上图
微信小程序的开发踩坑_第1张图片

二. setData修改的类型是对象的话

我们知道小程序更改data里面字段值的话,要这样

this.setData({
    name: '小程序'
})

这种情况比较常见,但是如果是对象的话,要用中括号括起来,也可以只加个字符串

this.setData({
['info.isLike']:  true
});

this.setData({
'info.isLike':  true
});

还有一个情况,如果是要修改数组里面某个项的值,一定是双括号,模板字符串也不行,会报错

let targetIndex = 0;
this.setData({
['messages['+ targetIndex +'].isLoad']:false
})

三. 自定义顶部导航栏

原生的顶部导航栏功能太少,比如没有个人头像,没有回到主页等等。所以很多时候都会要求自己写一个

步骤一:app.json文件写上这句话
加了这句话自带的导航栏就会消失

"window": {
    "navigationStyle": "custom" //加上这句话
}

步骤二:自己写一个组件,高度的话可以参考这样

wx.getSystemInfo({
success: (res) => {
let  device  =  res.platform;
let  statusBarH  =  res.statusBarHeight;

// 自定义导航栏高度,ios设置44px,安卓端48px
if (device  ===  'ios') {
this.globalData.navbarHeight  =  statusBarH  +  44;
} else {
this.globalData.navbarHeight  =  statusBarH  +  48;
}

// 手机状态栏高度
this.globalData.statusbarHeight  =  statusBarH;
// 手机系统
this.globalData.deviceSystem  =  device;
}
});

步骤三:这个组件记得要有高度占位,不能让页面去适配这个组件的高度去搞什么padding-top那些

四. 自定义底部导航栏

跟顶部的原因一样,很多功能无法满足,要自定义,这里提一个点,使用自定义之后,切换页面的时候会有明显的抖动
为了解决这个问题,我们把一级页面全部变成了组件,用组件切换来代替页面切换,大概是这样


  
  

五. 小程序接入微信支付

由于这块当时的开发不是我,所以我对整个流程不是很了解,从代码上面的能够得到的信息是:
小程序端:支付要调两次接口
第一次:预支付交易单付交易单
后端提供,这个接口会返回下一个接口所需要的参数

第二次:调用微信的支付api wx.requestPayment
调了这个之后才是真正的支付

ps:如果支付失败,比如那个支付输入密码的窗口,用户点了关闭,这个时候如果重新支付的话,必须走上面两个步骤
参考微信支付

六. 小程序使用npm

大概记录一下步骤
第一步:在文件夹初始化,输入npm init

npm init   //初始化

第二步:安装,这里举个例子,安装vant的ui库

npm i vant-weapp -S --production    //安装vant

第三步:在开发者,工具那里点一下构建
微信小程序的开发踩坑_第2张图片
构建完成后根目录下会显示miniprogram_npm文件夹
微信小程序的开发踩坑_第3张图片

第四步:修改项目设置
微信小程序的开发踩坑_第4张图片

第五步:使用测试一下,这里引入不用带上miniprogram\_npm
image.png
微信小程序的开发踩坑_第5张图片

PS: 这种引入的方法跟我们平时下载dist文件夹然后扔进去是一样的,并不能做到按需引入,我重点是想说明这个。

六. 说几个app.json配置的

  • 1 分包预加载

    "preloadRule": {
      "pages/home/index":{
        "network": "all",
        "packages": ["packages/destination"]
      }
    },

    这个是分包预加载,如果你不想点击分包的内容出现,正在下载模块的提示,可以加这个配置,但是我不确定这个到底会不会延长整个小程序的加载时间,按道理来说应该会?

  • 2 让用户授权位置信息的提示语

    "permission": {
      "scope.userLocation": {
        "desc": "您的位置信息将用来提供推荐地点"
      }
    },

七. 说一下project.config.json这个文件

这个是小程序创建项目的时候就会有的,我提一个点

"packOptions": {
        "ignore": [
            {
                "type": "folder",
                "value": "images/cdn"
            }
        ]
    },

这个是我在项目里有用到的,什么意思呢?就是我上传代码或者编译的时候,它会帮我忽略这个images/cdn文件夹下面的全部文件,因为我们项目里面用到cdn,因为按道理,用了cdn,本地图片肯定要删掉是吧,但是我们没有删除,选择放到这个文件夹里面,方便我们排查什么图片上传到cdn了。
你问那开发的时候怎么开发?
emmmm,是比较麻烦,在开发的时候用本地图片,当本地图片上传到cdn,并且你代码里面的src也换成了cdn之后,要手动挪到cdn文件夹

七. 说一说behavior

behavior就是vue的mixin,可以抽离公用的data,方法,生命周期等等,小程序的的页面和组件都能够使用,但是要区别写法,比如页面的是onload,组件是created;
7.1 写法:

基本写法,behavior的写法是参考组件的,所以有一些配置在页面上是不生效的

this.behavior = {
      options: {
        styleIsolation: 'apply-shared'
      },
       created() {
          let that = this
          this.$_themeChange = function(temtemtem){
            
            that.setData({
              $_theme: temtemtem.target.a,
              $_limit: temtemtem.target.b
            });
            console.log("组件的setData", temtemtem);
          };
        },

        attached() {
          this.setData({
            $_theme: Theme.currentTheme,
            $_limit: Theme.currentLimit
          });
        },

      methods: {
        setTheme(str) {
          Theme.currentTheme = str;
        }
      }
    };

7.2 用法:
page,Component的都一样

Page,Component({
  behaviors: [myBehavior],
  onLoad: function() {
    this.data.sharedText === 'This is a piece of data shared between pages.'
  },
  created(){}
})

八. 关于引入阿里云图标库

首先,登录阿里云图标库,点击那个下载至本地
下载完后,用这个转换网站(htt啦啦ps://tran啦啦sfonter.o啦啦rg/)
微信小程序的开发踩坑_第6张图片
按照上面勾上,点add fonts,把你下载后的ttf后缀文件传上去,然后点convert,转换后下载
把下载后的stylesheet文件,全部复制到你新创建的wxss文件,还没完
把阿里云下载至本地的,iconfont文件,除了@font那段不要,其他都复制。
最终的文件是这样
微信小程序的开发踩坑_第7张图片

九. 关于引入echarts

首先,去gitcode(mirrors/ecomfe/echarts-for-weixin镜像仓库,访问速度快)找到echarts的小程序的代码仓库,下载,
如果包太大你忍受不了,你就去定制生成,然后替换掉下载的echartsjs,这个在gitcode那有详细说明

关于踩坑的

一. 微信端

1.自动更新是做不到无感知的

版本有更新的话,用户一定会看到弹窗,一定要点一下确定按钮

更新:2020-07-03
好像可以无感更新了???不知道是不是最新版的微信支持了,反正是没看到弹窗了

2.组件拿不到app.wxss里面的样式

更新1:2020-04-08
自定义组件要拿到app的样式,或者当前引入页面的样式的话,要在组件里面加这么一句话

options:{
    addGlobalClass: true
  },

3.data里面直接定义app的global全局参数的话,如果中途变了,可能data里面的字段不会实时更新

global数据如果中途值改变了,页面或者组件里面的data里面初始化的那个值不会改变的,所以要额外处理

data: {
    vipCode:  app.global.vipCode  // vip版本
},

ready() {
// 有时候app全局值改变了,data里面的值没有同步
this.setData({
    vipCode:  app.global.vipCode
});
},

4. canvas画图的图片要先用wx.getImageInfo下载下来,拿临时路径才能用

更新1:2020-05-25
反正就是要临时路径才能画,你也可以downloadFile

更新2:2021/1/13
base64图片如何转成临时路径画

/**
 * base64图片转换
 * @param {*} imgData //base64图片
 * @returns
 */
function base64Image(imgData){
  var imgBaseData = imgData;
  const fsm = wx.getFileSystemManager();
  const FILE_BASE_NAME = 'tmp_base64src';
  return new Promise((resolve, reject) => {
      const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(imgBaseData) || [];
      if (!format) {
          reject(new Error('ERROR_BASE64SRC_PARSE'));
      }
      const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;
      const buffer = wx.base64ToArrayBuffer(bodyData);
      fsm.writeFile({
          filePath,
          data: buffer,
          encoding: 'binary',
          success() {
              resolve(filePath);
          },
          fail() {
              reject(new Error('ERROR_BASE64SRC_WRITE'));
          },
      });
  });
}

5. 小程序文本框自带手机键盘的高度,监听focus事件可以获取到

写聊天页面的时候,为了解决输入框要顶上,但是聊天列表不顶上的问题。