微信小程序遇到的坑(持续更新中······)

2,124 阅读3分钟

最近接手他人开发的微信小程序项目,在学习开发过程中遇到许多问题,这篇文章将不定时更新工作中遇到的一些坑(持续更新中·····)

page 和 component 差异性

微信小程序和vue项目不同,vue项目中都是由组件堆积而成,小程序page是页面,它是由Page({})对象组成,component是组件,它是由Component({})对象组成,所以在原page页面拆分出component组件时,遇到一系列坑

1、page调用component对象

如果page A 中存在 component B,如果在A中调用B组件中 data、method,可以用单例模式获取B组件实例,例如:

getComponentB () {
    let componentBInstance = this.data.componentBInstance
    return new Promise((resolve, reject) => {
      if (!componentB) {
        this.setData({
          componentBInstance: this.selectComponent('#component_b')
        }, () => {
          resolve(this.data.componentBInstance)
        })
      } else {
        resolve(this.data.componentBInstance)
      }
    })
  },

这种写法有助于多次调用时,不用重复调用微信小程序方法selectComponent(ps:此项不是差异哈,请继续往下看撒)

2、this引发的问题

在page A页面直接使用如下代码片段

let query = wx.createSelectorQuery();
query.select('#component_b').boundingClientRect()
query.exec(res => {
  console.log(res)
})

此时component_b还未拆分成组件B,上面的代码片段一点问题没有,但是如果已经分离出来,那么打印出来的结果是null,微信官方给的文档是

SelectorQuery.in(Component component)将选择器的选取范围更改为自定义组件 component 内。(初始时,选择器仅选取页面范围的节点,不会选取任何自定义组件中的节点) 所以上述代码需改成

let query = wx.createSelectorQuery().in(this);
query.select('#component_b').boundingClientRect()
query.exec(res => {
  console.log(res)
})

2、this引发wx-charts.js

在小程序中可视化操作时,需区分page还是component,在wx-charts.js源码中使用是wx.createCanvasContext(canvasId),page页面能正常使用,但是在component中需添加this指向,所以在组件环境下改动如下:


初始化改动

// echarts图初始化
      let chart = new Charts({
        canvasId: 'columnCanvas',
        type: 'column',
        categories: ['**', '**'],
        column: {
          legendTextColor: '#999'
        },
        series: [{
          name: '**',
          color: "#FFAE00",
          data: [1, 1]
        }, {
          name: '**',
          color: "#368FFF",
          data: [1, 1]
        }],
        xAxis: {
          gridColor: '#E9EFF5',
          disableGrid: true
        },
        yAxis: {
          min: 0,
          gridColor: '#E9EFF5',
          disabled: false,
          format: function (val) {
            return '';
          }
        },
    _that: this   // 添加参数_that,传入单前组件对象this
  });


wx-charts.js 源码改动

var Charts = function Charts (opts) {
    opts.title = opts.title || {};
    ......
    this.context = wx.createCanvasContext(opts.canvasId, opts._that || null); // 重点改这儿
    ......
    drawCharts.call(this, opts.type, opts, config?1, this.context);
};

将源码wx.createCanvasContext(opts.canvasId) 改成 wx.createCanvasContext(opts.canvasId, opts._that || null)

3、cavans 新版本兼容问题

新版本canvas 新增type属性,如下列表

属性 类型 默认值 必填 说明 最低版本
type string 指定 canvas 类型,支持 2d (2.9.0) 和 webgl (2.7.0) 2.7.0

你如果使用wx.createCanvasContext 就不要加这个type属性,不然上面wx-charts.js也获取不到canvas上下文

模块引用

1、require 引用问题

小程序单独写a.js类型文件一般都是如下结构:

function a() {}
module.exports = a

我所在的项目在page页面使用如下引用方式没问题

const a = require("./a.js")

但是在其他js文件引用时会出现undefined,所以利用微信小程序官方写法,修改a.js文件如下

function a() {}
module.exports = a
exports.A = a

2、component组件内联样式问题

<component-b style="background: #fff"></component-b>

在组件B中调用组件A,并在此组件A上使用内联样式可能不生效,类名样式也不生效,曲线解决方式

:host{
background: #fff
}

上面用到的场景不适合,建议在原A组件内添加

options: {
  styleIsolation: 'apply-shared'
}

敬请期待

持续更新总结