You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用destroy()后返回页面添加数据仍提示Canvas已被占用

解决Canvas重复使用的Chart.js错误

问题详情

  • 错误提示:Canvas is already in use. Chart with ID ' ' must be destroyed before the canvas with ID 'MyChart' can be reused.
  • 控制台中该错误会针对特定ID重复出现4-5次
  • 当前页面内添加数据无报错,但切换页面再返回组件添加数据时触发错误

现有代码

if (this.chart){
    this.chart.destroy(); 
}  
this.chart = new Chart('MyChart', {
    type: 'line',
     data: {
     labels: monthLabels,
     datasets: [
      {
        label: 'Weight',
        data: weightLabels,
        backgroundColor: 'blue',
      },
    ],
  },
  options: {
    aspectRatio: 2.5,        
  },
}); 

解决方案

问题核心是组件切换时,旧的Chart实例未被正确销毁或引用丢失,导致复用Canvas时冲突。

1. 组件卸载时强制清理实例

在组件的卸载生命周期钩子中添加销毁逻辑,确保离开页面时彻底清理:

  • Vue示例:
beforeUnmount() {
  if (this.chart) {
    this.chart.destroy();
    this.chart = null; // 清空引用,避免内存泄漏
  }
}
  • React函数组件示例:
useEffect(() => {
  const chartInstance = new Chart('MyChart', {
    type: 'line',
    data: { labels: monthLabels, datasets: [{
        label: 'Weight',
        data: weightLabels,
        backgroundColor: 'blue',
      }] },
    options: { aspectRatio: 2.5 }
  });

  // 组件卸载时销毁实例
  return () => {
    chartInstance.destroy();
  };
}, [monthLabels, weightLabels]); // 依赖数据变化时重新创建图表

2. 直接从Canvas获取并销毁旧实例

如果this.chart引用失效,可通过Chart.js的API直接从Canvas元素获取绑定的实例:

const canvas = document.getElementById('MyChart');
// 检查Canvas上是否已有Chart实例(Chart.js v3+支持)
const existingChart = Chart.getChart(canvas);
if (existingChart) {
  existingChart.destroy();
}
// 用DOM元素而非ID初始化,避免ID选择器的潜在问题
this.chart = new Chart(canvas, {
    type: 'line',
    data: { labels: monthLabels, datasets: [{
        label: 'Weight',
        data: weightLabels,
        backgroundColor: 'blue',
      }] },
    options: { aspectRatio: 2.5 }
});

3. 控制图表初始化时机

确保图表初始化逻辑仅在组件挂载或数据更新时执行,避免在重复触发的钩子中多次调用。

内容的提问来源于stack exchange,提问作者user17449555

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 01:27:16