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更新又会触发图表重新渲染,形成递归循环,最终触发超限警告。
修复步骤
- 切断响应式关联,使用数组副本:在
updateChartSeries中,不要直接赋值Store数组,而是创建副本,避免双向响应式绑定:
const updateChartSeries = () => { // 浅拷贝数组,切断与Store的直接引用 chartSeries.value[0].data = [...adquisicionStore.hornoMarcha]; // 若数据包含嵌套对象,需使用深拷贝:JSON.parse(JSON.stringify(adquisicionStore.hornoMarcha)) }
- 优化配置的响应式追踪:
chartOptions是静态配置,无需被Vue响应式系统追踪,用readonly包装减少不必要的重渲染:
import { ref, onMounted, readonly } from "vue"; const chartOptions = readonly({ // 原配置内容不变 });
- 确认数据格式合规:检查后端返回的
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
相关产品推荐
相关产品推荐

