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

VueJS中ChartJS图表悬停闪烁,destroy函数调用位置咨询

Fixing Chart.js Stacked Bar Chart Flickering in VueJS

Hey, I've run into this exact Chart.js flickering issue with Vue before—let's break down how to fix it properly. The root problem here is that you're probably creating new chart instances without cleaning up the old ones, which causes the hover state to conflict between overlapping instances. Here's how to get this sorted:

1. Store the Chart Instance in Vue's Component State

Stop using a global myBarChart variable—instead, keep the instance in your component's data so Vue can track it properly. This avoids "chart is undefined" errors because you'll always have a reference to the instance within the component context:

export default {
  data() {
    return {
      myBarChart: null,
      dayMonth: [] // Your labels array here
    };
  },
  // ... rest of your component
};

2. Destroy Old Instances Before Creating New Ones

Before initializing a new chart, check if an existing instance exists, destroy it, and reset the reference. This ensures you never have multiple charts attached to the same canvas element:

methods: {
  renderMonthVisitsChart() {
    const ctx = document.getElementById("month-visits-chart").getContext('2d');

    // Clean up existing chart first
    if (this.myBarChart) {
      this.myBarChart.destroy();
      this.myBarChart = null;
    }

    // Initialize new chart
    this.myBarChart = new Chart(ctx, {
      type: 'bar',
      data: {
        labels: this.dayMonth,
        datasets: [
          // Your stacked datasets here
        ]
      },
      options: {
        responsive: true,
        scales: {
          y: { stacked: true },
          x: { stacked: true }
        }
        // Add your other options here
      }
    });
  }
}

3. Call the Render Method at the Right Times

  • Initial Render: Call your chart rendering method in the mounted hook—this ensures the canvas element exists in the DOM before you try to access it:
mounted() {
  this.renderMonthVisitsChart();
}
  • Data Updates: If your dayMonth (or dataset) data changes dynamically, use a watcher to re-render the chart when the data updates:
watch: {
  dayMonth(newLabels) {
    // Only re-render if we have valid labels
    if (newLabels.length > 0) {
      this.renderMonthVisitsChart();
    }
  }
}

4. Clean Up on Component Destroy

Prevent memory leaks by destroying the chart instance when the component is about to be unmounted:

// Vue 3
beforeUnmount() {
  if (this.myBarChart) {
    this.myBarChart.destroy();
  }
}

// Vue 2 (use this instead)
beforeDestroy() {
  if (this.myBarChart) {
    this.myBarChart.destroy();
  }
}

The "chart is undefined" error you saw earlier was likely because your global myBarChart variable wasn't being initialized before you tried to call destroy() on it. By keeping the instance in the component's data, you always have a valid reference to check against before attempting to destroy it.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:33:31