老项目使用的是 taro-1.3,最近把taro升级到 taro-3.0,在此记录一下遇到的问题
ec-canvas 不能正常运行使用
错误一
TypeError: this.Chart.init is not a function
at LineChart.refresh (._src_pages_user_assets_components_chart_LineChart2.js:62)
at UserTest.componentDidMount (._src_pages_user_user-test_user-test.jsx:45)
at Lf (._node_modules_react-reconciler_cjs_react-reconciler.production.min.js:133)
at hh (._node_modules_react-reconciler_cjs_react-reconciler.production.min.js:172)
at define.push../node_modules/scheduler/cjs/scheduler.production.min.js.exports.unstable_runWithPriority (._node_modules_scheduler_cjs_scheduler.production.min.js:18)
at Pc (._node_modules_react-reconciler_cjs_react-reconciler.production.min.js:36)
at Zg (._node_modules_react-reconciler_cjs_react-reconciler.production.min.js:169)
at Og (._node_modules_react-reconciler_cjs_react-reconciler.production.min.js:160)
at ._node_modules_react-reconciler_cjs_react-reconciler.production.min.js:37
at define.push../node_modules/scheduler/cjs/scheduler.production.min.js.exports.unstable_runWithPriority (._node_modules_scheduler_cjs_scheduler.production.min.js:18)(env: Windows,mp,1.05.2109101; lib: 2.19.5)
报错原因: 升级后 taro3 不能通过ref
直接获取原生微信小程序组件,实际获取的是 TaroElement
,
我们可以通过 getCurrentInstance().page.selectComponent('#mychart-area')
方式获取微信原生小程序Node:
import Taro, { getCurrentInstance } from "@tarojs/taro"
getCurrentInstance().page.selectComponent('#mychart-area').init((canvas, width, height) => {
console.log('canvas', canvas)
const chart = echarts.init(canvas, null, {
width: width,
height: height
});
setChartData(chart, data);
return chart;
});
TaroElement
原生小程序Node
修复以上问题后,又报新的错误:
错误二
TypeError: t.addEventListener is not a function
at te (._src_pages_user_assets_components_ec-canvas_echarts.js:37)
at Oi (._src_pages_user_assets_components_ec-canvas_echarts.js:37)
at ._src_pages_user_assets_components_ec-canvas_echarts.js:37
at Array.forEach (<anonymous>)
at P (._src_pages_user_assets_components_ec-canvas_echarts.js:37)
at ki (._src_pages_user_assets_components_ec-canvas_echarts.js:37)
at new e (._src_pages_user_assets_components_ec-canvas_echarts.js:37)
at new t (._src_pages_user_assets_components_ec-canvas_echarts.js:44)
at Hi (._src_pages_user_assets_components_ec-canvas_echarts.js:44)
at new e (._src_pages_user_assets_components_ec-canvas_echarts.js:44)(env: Windows,mp,1.05.2109101; lib: 2.19.6)
经过一番研究之后发现,t.addEventListener
中的t
就是我们的echarts.init
方法中的canvas
参数,而canvas
是 ec-canvas/wx-canvas
中类 WxCanvas
的实例,尝试在该类中添加 addEventListener
方法,错误成功修复😅。
const chart = echarts.init(canvas, null, {
width: width,
height: height
});
// wx-canvas.js
export default class WxCanvas {
constructor(ctx, canvasId, isNew, canvasNode) {
this.ctx = ctx;
this.canvasId = canvasId;
this.chart = null;
this.isNew = isNew
if (isNew) {
this.canvasNode = canvasNode;
}
else {
this._initStyle(ctx);
}
// this._initCanvas(zrender, ctx);
this._initEvent();
}
// 新增空函数,修复调用 echarts.init 时报错
addEventListener () {}
getContext(contextType) {
if (contextType === '2d') {
return this.ctx;
}
}
}
完整代码
// pages/index/index.js
import _ from 'lodash'
import React, { Component } from 'react'
import { View } from '@tarojs/components'
import './user-test.less'
import LineChart from '../assets/components/chart/LineChart'
function createChartData () {
let seriesDataLine = []
let progressLine = [1,3,2,6,8,2]
if (progressLine && progressLine.length) {
seriesDataLine = _.map(progressLine, item => {
return {
value: item,
label: {
position: item >= 0 ? 'top' : 'bottom'
}
}
})
} else {
seriesDataLine = [0, 0, 0, 0, 0, 0]
}
const chartData = {
dimensions: {
// data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
measures: [{
data: seriesDataLine
}]
}
return chartData
}
export default class UserTest extends Component {
constructor (props) {
super(props)
this.lineChart = React.createRef()
this.state = {
}
}
componentWillMount () {}
componentDidMount () {
// 延迟调用,确保 ec-canvas 节点已存在
setTimeout(() => {
this.lineChart.current.refresh(createChartData())
}, 100)
}
componentWillUnmount () { }
componentDidShow () { }
componentDidHide () { }
render () {
return (
<View className='page-user-test'>
<View className='line-chart'>
<LineChart ref={this.lineChart} />
</View>
</View>
)
}
}
// LineChart.js
import { Component } from "react"
import { getCurrentInstance } from "@tarojs/taro"
import * as echarts from "../ec-canvas/echarts"
function setChartData(chart, data) {
let option = {
color: ['#FF4040'],
xAxis : [
{
type: 'category',
data: [],
axisTick: {
alignWithLabel: true
}
}
],
grid: {
left: '5%',
right: '5%',
top: '20',
bottom: '5',
containLabel: true
},
yAxis : [
{
type : 'value'
}
],
series : []
};
if (data && data.dimensions && data.measures) {
option.xAxis[0].data = data.dimensions.data
option.series = data.measures.map(item => {
return {
...item,
type:'line',
smooth: true
}
})
}
chart.setOption(option);
}
export default class LineChart extends Component {
constructor(props) {
super(props)
this.state = {
ec: {
lazyLoad: true
}
}
}
componentDidMount () {}
refresh(data) {
getCurrentInstance().page.selectComponent('#mychart-area').init((canvas, width, height) => {
console.log('canvas', canvas)
const chart = echarts.init(canvas, null, {
width: width,
height: height
});
setChartData(chart, data);
return chart;
});
}
render() {
return (
<ec-canvas
id='mychart-area'
canvasId='mychart-area'
ec={this.state.ec}
/>
);
}
}
相关链接