首页 > 建站教程 > 前端框架 >  解决 ECharts 报错:Uncaught TypeError: Cannot read properties of undefined (reading 'type')正文

解决 ECharts 报错:Uncaught TypeError: Cannot read properties of undefined (reading 'type')

这个问题困扰了我好久,就是在做 ECharts + Vue 的可视化图表时,出现了一个错误:

Uncaught TypeError: Cannot read properties of undefined (reading 'type')

这个错误发生在点击 ECharts 图例(legend)时,导致图表重新渲染时出现冲突。分析原因,发现问题源于 ECharts 自己管理的状态与 Vue 的响应式数据管理之间的冲突。

解决 ECharts 报错:Uncaught TypeError: Cannot read properties of undefined (reading 'type')


错误原因

Vue 的响应式系统和 ECharts 依赖的内部状态机制(例如图表的 series 和 legend 选项)在某些情况下没有正确同步。尤其是在图例(legend)切换时,ECharts 会自动更新图表的状态和数据,但由于 Vue 的数据响应式更新机制,ECharts 的内部数据对象变为 undefined,从而引发了 Uncaught TypeError: Cannot read properties of undefined (reading 'type') 错误。


解决方法:

🌟使用 markRaw 去除响应式

Vue 3 提供了 markRaw API,可以将某个对象标记为非响应式,从而防止 Vue 对该对象进行代理。对 ECharts 实例或其配置对象使用 markRaw,可以让它完全由 ECharts 自己管理状态,避免 Vue 的响应式与 ECharts 内部状态冲突。


核心步骤

1、在 Vue 组件中导入 markRaw:

import { ref, onMounted, markRaw } from 'vue';


2、在创建 ECharts 实例前,用 markRaw 包装实例引用:

const chartInstance = ref();
chartInstance.value = markRaw(echarts.init(dom));


3、之后通过 chartInstance.value 操作图表,不会触发 Vue 的响应式代理。


完整代码

import { ref, onMounted, markRaw } from 'vue';
import * as echarts from 'echarts';
const chartInstance = ref();
onMounted(() => {
  const dom = document.getElementById('chart');
  // 使用 markRaw 保持原始对象
  chartInstance.value = markRaw(echarts.init(dom));
  const option = {
    tooltip: { trigger: 'axis' },
    legend: {
      data: ['示例系列'],
      selectedMode: false
    },
    xAxis: { type: 'category', data: ['A', 'B', 'C'] },
    yAxis: { type: 'value' },
    series: [{
      name: '示例系列',
      type: 'line',
      data: [120, 200, 150]
    }]
  };
  chartInstance.value.setOption(option);
  chartInstance.value.on('legendselectchanged', params => {
    // 自定义交互,不会触发内部冲突
    const sel = params.selected['示例系列'];
    const maxVal = sel ? Math.max(...option.series[0].data) : 0;
    chartInstance.value.setOption({
      yAxis: { max: maxVal }
    });
  });
});


总结

通过对 ECharts 实例或其选项对象使用 markRaw,可以彻底剥离 Vue 的响应式系统,避免两者在图例切换等场景下的状态冲突,从根本上解决 Uncaught TypeError: Cannot read properties of undefined (reading 'type') 问题。