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

Vue递归更新超限警告:路由加载慢且菜单异常排查

问题:递归更新超限警告导致组件加载缓慢、菜单异常

收到以下Vue警告,打开路由时组件加载缓慢,菜单出现异常:

[Vue warn]: Maximum recursive updates exceeded. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function

怀疑问题与Store中的数据处理有关。


前端组件代码(绘制rangeBar图表)

<template>
    <q-page>
      <div class="q-pa-md">
        <VueApexCharts
          v-if="!adquisicionStore.loading"
          type="rangeBar"
          height="200" 
          :options="chartOptions" 
          :series="chartSeries"
        />
      </div>
    </q-page>
 </template>

<script setup>
  import VueApexCharts from "vue3-apexcharts";
  import { useAdquisicion } from "../stores/main";
  import { ref, onMounted } from "vue";
  
  const adquisicionStore = useAdquisicion();
  
  const chartSeries = ref([
    {
      name: 'horno1',
      data: [],
    }
  ]);
  
  const chartOptions = {
    plotOptions: {
      bar: {
        horizontal: true,
        barHeight: '20%'
      }
    },
    xaxis: {
      type: 'datetime'
    },
    stroke: {
      width: 1
    },
    fill: {
      type: 'solid',
      opacity: 0.6
    },
    legend: {
      position: 'top',
      horizontalAlign: 'left'
    }
  };  
  
  onMounted(async () => {
    await adquisicionStore.loadHornoMarcha();
    updateChartSeries();
  });
  
  const updateChartSeries = () => {
    // Make sure adquisicionStore.hornoMarcha is an array of data
    chartSeries.value[0].data = adquisicionStore.hornoMarcha;
  }
</script>

Pinia Store代码

import { defineStore } from 'pinia';
import axios from 'axios';

export const useAdquisicion = defineStore('adquisicion', {
  state: () => ({
    hornoMarcha: [],
    loading: true
  }),

  actions: {

      async loadHornoMarcha() {
        try {
          const responseHorMar = await axios.get('http://localhost:3000/horno-marcha');
          if (responseHorMar.status === 200) {
            this.hornoMarcha = responseHorMar.data;
            this.loading = false;
          } else {
            console.error('Error al obtener datos: Respuesta no válida');
          }
        } catch (error) {
          console.error('Error al obtener datos:', error);
        }
      },

  },
  
});

解决方案

问题根源

当前代码中,chartSeries.value[0].data直接引用了Store中的adquisicionStore.hornoMarcha数组,导致图表组件与Store状态建立了深层响应式关联。当图表渲染时(比如ApexCharts内部处理数据)可能会修改该数组,进而触发Store状态更新,Store更新又会触发图表重新渲染,形成递归循环,最终触发超限警告。

修复步骤

  1. 切断响应式关联,使用数组副本:在updateChartSeries中,不要直接赋值Store数组,而是创建副本,避免双向响应式绑定:
const updateChartSeries = () => {
  // 浅拷贝数组,切断与Store的直接引用
  chartSeries.value[0].data = [...adquisicionStore.hornoMarcha];
  // 若数据包含嵌套对象,需使用深拷贝:JSON.parse(JSON.stringify(adquisicionStore.hornoMarcha))
}
  1. 优化配置的响应式追踪:chartOptions是静态配置,无需被Vue响应式系统追踪,用readonly包装减少不必要的重渲染:
import { ref, onMounted, readonly } from "vue";

const chartOptions = readonly({
  // 原配置内容不变
});
  1. 确认数据格式合规:检查后端返回的horno-marcha数据是否完全符合ApexCharts rangeBar的要求,格式错误也可能引发组件异常渲染。

额外优化

如果Store中的hornoMarcha会频繁更新,可在组件中监听Store状态变化自动更新图表,同时保持使用副本:

import { watch } from "vue";

watch(() => adquisicionStore.hornoMarcha, (newData) => {
  chartSeries.value[0].data = [...newData];
}, { deep: true });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 19:40:41