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

Vue-chartjs 传入chartData作为prop时首次加载不渲染,仅窗口resize后正常显示

问题产生原因

  • 时序错位:子组件mounted钩子执行渲染逻辑时,父组件的setChartsTimesheets数据填充方法还未执行完成,此时传入的chartData是空结构,首次渲染没有有效内容。
  • 深层属性修改无法触发响应式重绘:父组件更新chartData时,是直接修改对象内部嵌套数组的元素(如push操作修改labels、datasets[0].data等属性),而vue-chartjs自带的reactiveProp混入默认仅做浅层监听,无法捕获到深层属性的变更,因此数据更新后图表不会主动刷新。
  • 调整窗口时触发了Chart.js内置的resize重绘逻辑,此时chartData已经填充完成,所以图表会正常显示。

解决方案

方案1(优先推荐):父组件控制子组件渲染时机

等chartData数据填充完成后再渲染子组件,避免空数据渲染的问题:

  1. 父组件新增加载状态标识:
data() {
  return {
    chartLoaded: false,
    // 其余原有属性不变
  }
}
  1. 父组件setChartsTimesheets方法执行完成后修改加载状态:
setChartsTimesheets() {
  // 原有逻辑不变
  this.chartLoaded = true
}
  1. 父组件模板中通过v-if控制子组件渲染:
<v-container>
  <ProjectDoughnutChart v-if="chartLoaded" :chart-data="chartData" />
</v-container>

方案2:子组件开启深层监听主动重绘

在子组件中新增watch深层监听chartData变化,主动触发图表更新:

// 子组件新增watch配置
export default {
  extends: Doughnut,
  mixins: [reactiveProp],
  mounted() {
    this.render();
  },
  watch: {
    chartData: {
      deep: true,
      handler() {
        // 图表已实例化则调用update,否则执行首次渲染
        if (this.$data._chart) {
          this.$data._chart.update()
        } else {
          this.render()
        }
      }
    }
  },
  methods: {
    // 原有render方法不变
  }
}

方案3:父组件替换整个chartData对象触发响应式

修改父组件的数据更新逻辑,不直接修改原chartData的内部属性,而是构造全新的chartData对象再赋值,触发reactiveProp的浅层监听:

setChartsTimesheets() {
  // 构造全新的chartData对象
  const newChartData = {
    labels: [],
    datasets: [
      {
        backgroundColor: [],
        hoverBackgroundColor: [],
        data: [],
      },
    ],
  }
  this.timesheets.forEach((timesheet) => {
    let typeTotal = 0;
    this.timesheets
      .filter((timesheet1) => timesheet1.type==timesheet.type)
      .forEach((timesheet1) => {
        typeTotal+=timesheet1.billableAmount;
      });
    if (newChartData.labels.indexOf(timesheet.type) === -1) {
      let colors = this.getTaskColors(timesheet.type);
      newChartData.labels.push(timesheet.type);
      newChartData.datasets[0].data.push(typeTotal);
      newChartData.datasets[0].backgroundColor.push(colors.color);
      newChartData.datasets[0].hoverBackgroundColor.push(colors.hover);
    }
  });
  // 替换整个对象触发响应式更新
  this.chartData = newChartData
},

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 14:06:03