原文链接:解决 Vue 中应用 Echarts 呈现 There is a chart instance already initialized on the dom 的正告问题
问题形容
应用echarts
的时候,屡次加载会呈现There is a chart instance already initialized on the dom.
这个黄色正告,大略意思就是dom
上曾经初始化了一个图表实例。此正告信息不影响echarts
失常加载,然而有bug
不解决的话,心里痒的慌!
先阐明一下,echarts
是用在了子组件的弹窗里,而后在父组件关上弹窗时调用echarts.init()
的初始化办法。第一次渲染失常,之后再关上弹窗控制台就会报There is a chart instance already initialized on the dom.
父组件中的代码:
const taskDetailDom = ref()const open = ()=> { if (taskDetailDom.value) { taskDetailDom.value.initEchart() }}
如何造成的? 这里只区别了子组件的写法。
谬误写法:
<script setup lang='ts'>import echarts from "@/utils/custom/echart"let tChart: Ref<HTMLDivElement | null> = ref(null)const initEchart = () => { const dom = tChart.value if (dom) { let myChart = echarts.init(dom) myChart.setOption(option) }}defineExpose({ initEchart})
对于import echarts from "@/utils/custom/echart"
此处中的代码(可参考官网示例)如下:
import * as echarts from 'echarts/core';import { BarChart, LineChart, PieChart} from 'echarts/charts';import { LegendComponent, TitleComponent, TooltipComponent, GridComponent, // 数据集组件 DatasetComponent, // 内置数据转换器组件 (filter, sort) TransformComponent} from 'echarts/components';import { LabelLayout, UniversalTransition } from 'echarts/features';import { CanvasRenderer } from 'echarts/renderers';import type { // 系列类型的定义后缀都为 SeriesOption BarSeriesOption, LineSeriesOption} from 'echarts/charts';import type { // 组件类型的定义后缀都为 ComponentOption LegendComponentOption, TitleComponentOption, TooltipComponentOption, GridComponentOption, DatasetComponentOption} from 'echarts/components';import type { ComposeOption,} from 'echarts/core';// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型type ECOption = ComposeOption< | BarSeriesOption | LegendComponentOption | LineSeriesOption | TitleComponentOption | TooltipComponentOption | GridComponentOption | DatasetComponentOption>;// 注册必须的组件echarts.use([ LegendComponent, TitleComponent, TooltipComponent, GridComponent, DatasetComponent, TransformComponent, BarChart, LineChart, PieChart, LabelLayout, UniversalTransition, CanvasRenderer]);export default echarts;
解决办法
在办法最外层定义echarts dom
对象,而后echarts.init()
之前,判断dom
是否为空或未定义,如果已存在则调用dispose()
办法销毁,再初始化echarts.init()
。
let tChart: Ref<HTMLDivElement | null> = ref(null)let myChart: any // 1. 最外层定义 echarts domconst initEchart = () => { const dom = tChart.value if (dom) { // 2. 判断 dom 是否为空或未定义 if (myChart != null && myChart != "" && myChart != undefined) { // 3. 已存在则调用 dispose() 办法销毁 myChart.dispose(); } myChart = echarts.init(dom) myChart.setOption(option) }}defineExpose({ initEchart})