实际上是开发微信小程序我踩过的一些坑,也是我的学习笔记,如果你想实现类似的功能,或者遇到类似问题,可以参考这篇文章。


  1. 针对多维数组,在原有数据的后面追加数据

    知识点:...扩展运算符,用于数组的展开。

    **情景:**包含时间、传感器值的二维数据的数组,形如[[11:45:14, 1.23], [11:45:15, 2.33]]。需要在后面插入相同形式的数据。

    **方法:**使用扩展运算符...展开原数组和追加数组,然后合并为新数组。

    例子:

    1
    2
    3
    const oldData = res.data || [];
    const newData = [...oldData, ...removed];
    wx.setStorageSync(currentDate, newData);

    Q&A:

    • **Q:**为什么不能直接写[oldData, removed]

      **A:**因为数组没展开,返回的是2个二维数组,是错误的结果。


  1. 从一个多维数组中提取指定内容,并构成新序列

    知识点:

    • **map方法:**将原数组映射为指定的形式,创建一个新数组,需要一个变量来承载新数组。
    • **=>箭头函数:**函数的简写,结构为参数 => 返回值,类似于C的lambda。会继承外部的this,保持其指向不变。

    **情景:**包含时间、传感器值的二维数据的数组,形如[[11:45:14, 1.23], [11:45:14, 2.33]]。需要从数组中提取时间轴和数值轴的数据序列,构成新数组,作为折线图的x轴和y轴数据源。

    **方法:**使用箭头函数提取指定的元素,用map方法将其映射为新的数组。

    例子:

    1
    2
    3
    const time = this.data.dataList.map(item => item[0]);
    const value = this.data.dataList.map(item => item[1]);
    // 对每个dataList处理一次,将其中的所有第0或第1个元素返回,映射到一个新数组,作为time或者value保存下来

  1. 处理错误的SetTimeout()函数

    知识点:SetTimeout()函数,延时结束后自动执行。延时单位是毫秒。

    **情景:**用户按下按钮,启动设备。你需要给用户返回不同的状态,你用SetTimeout()函数来判断超时,超时自动返回【连接失败】。

    你很聪明,想到了要用标志位来解决,也就是设置一个标志位,例如deviceState.start.success来表征设备启用状态,当你监听到设备启用,执行回调,把这个值设置为trueSetTimeout()延时结束后判断这个值的真假,阻止设备启动后,显示错误状态。

    但如果用户~~在酒馆里点了一份炒饭~~在设备成功启动后迅速点击关闭,然后再启用设备,假设上述过程在你设置的超时期限以内,那就会错误触发超时,返回【连接失败】。

    **方法:**在执行启动设备的指令成功后,清除定时器(前提是你能监听到执行成功)

    例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //延时函数,先用一个变量保存延时函数
    this.data.isDeviceLaunched = setTimeout(() => {
    if (!this.data.deviceState.start.success) {
    this.setDeviceState('start', 'fail');
    }
    }, 5000);

    //设备启用成功的回调
    () => {
    this.data.deviceState.start.success = true;
    this.setDeviceState('start', 'succcess');
    clearTimeout(this.data.isDeviceLaunched);
    },

  1. Echarts图表:启用tooltip/axisPointer时的undefined错误

    知识点:Echarts图表(如需使用,请先阅读官方文档)/ axisPointer / tooltip

    **情景:**你引用Apache Echarts图表,使用折线图来显示一些传感器的值随时间的变化。但是你发现,点击某个数据点的时候,你并不知道它具体的值是多少。你认为这对用户来讲不太友好。所以你引入了tooltip/axisPointer,希望能够帮用户读清楚数据。

    实际测试的时候,你发现了问题:假设10月20日的数据有5个点,10月21日的数据有2个点。当你点击10月20日的第3个数据,然后通过下拉菜单切换到10月21日。此时tooltip/axisPointer就有概率返回undefined值。

    原因:tooltip/axisPointer不会随着图表数据源的切换而刷新,原本10月21日的第3个点本来就没有值。

    **方法:**让需要的组件在切换数据源之后刷新一次就好了。

    例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //由constant.js引入,只需重置tooltip,xAxis,yAxis,series四项即可避免undefined错误
    export let newEchartsOption = {
    tooltip: echartsOption.tooltip,
    xAxis: echartsOption.xAxis,
    yAxis: echartsOption.yAxis,
    series: echartsOption.series
    }

    //用于重绘图表的函数
    redrawEchart() {
    var option = newEchartsOption
    this.chart.clear();
    this.chart.setOption(option, {
    replaceMerge: ['xAxis', 'yAxis', 'series', 'tooltip']
    });
    }

  1. 关于this

    通常,在 JS 中,this 的真正决定因素是 函数被调用的方式。this 的指向并不确定。

    而在微信小程序里,由于微信小程序框架会在你调用 Page() Component() 时自动创建一个对象实例。这个实例就是页面或组件的“运行时对象”。

    通常,一个页面自动创建的 JS ,结构是这样的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Page({
    data: {
    data1: 0,
    data2: {name1: 'test'}
    },

    onLoad(options) {

    },

    onReady() {

    },

    onShow() {

    },
    }

    在这里引用this,微信框架会使它指向这个Page下的实例。换句话说,需要引用Page下的东西,都可以用this

    例如引用data1,就是this.data.data1。引用name1test这个字串,就是this.data.data2.name1

    如果你在Page下自定义了一些函数,饮用方法也是如此。

    例如下面的代码,在onLoad里调用myFunction()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Page({
    data: {
    data1: 0,
    data2: {name1: 'test'}
    },

    onLoad(options) {
    this.myFunction();
    },

    myFunction() {
    console.log("myFunction");
    }
    }

    但是由于this的特性,也可能出现一些问题。

    例如在下面的代码中:

    1
    2
    3
    4
    5
    6
    7
    8
    wx.getStorageInfo({
    success: function (res) {
    console.log("成功读取缓存信息");
    this.setData({
    data1: res,
    });
    },
    })

    就会出现下面的报错:

    1
    this.setData is not a function

    这是由于this的作用域导致的。因为success是个闭包,无法直接获取外部的this结构,既然这些东西也就不存在。

    解决办法也很简单,就是使用箭头函数,或者先传入this,再用that集成。箭头函数会继承外层的this,不改变其指向。

    如下:

    1
    2
    3
    4
    5
    6
    7
    8
    wx.getStorageInfo({
    success: (res) => {
    console.log("成功读取缓存信息");
    this.setData({
    data1: res,
    });
    },
    })

持续更新中…