为何执行代码时出现RangeError: Maximum call stack size exceeded错误?
解决Vue中修改嵌套响应式数组导致栈溢出的问题
你遇到的栈溢出问题,大概率是直接修改ref包裹的嵌套响应式数组时,触发了重复的响应式更新循环。labels的push能正常执行,但datasets[0].data作为更深层的响应式数组,每次push都会触发组件响应式更新,若存在隐性的循环触发逻辑(比如模板渲染间接引发数据修改),就会导致栈溢出。
方案1:临时数组批量更新
先把数据复制到临时数组中修改,完成后一次性赋值给响应式属性,减少响应式触发次数:
const myData = ref({ labels: [] as string[], datasets: [ { data: [] as number[] } ] }); const handleCurrency = (origin) => { const tempLabels = [...myData.value.labels]; const tempData = [...myData.value.datasets[0].data]; origin.forEach(item => { tempLabels.push(item.item); tempData.push(item.percent); }); // 一次性赋值,仅触发一次响应式更新 myData.value.labels = tempLabels; myData.value.datasets[0].data = tempData; }; handleCurrency([{item: 'USD', percent: 1, value: 50}]);
方案2:拆分响应式变量
将嵌套数组拆分为独立的ref,避免深层嵌套的响应式更新冲突:
const labels = ref<string[]>([]); const datasetData = ref<number[]>([]); // 用computed组合成业务需要的结构 const myData = computed(() => ({ labels: labels.value, datasets: [{ data: datasetData.value }] })); const handleCurrency = (origin) => { origin.forEach(item => { labels.value.push(item.item); datasetData.value.push(item.percent); }); }; handleCurrency([{item: 'USD', percent: 1, value: 50}]);
额外排查点
若以上方案无效,检查代码是否存在以下情况:
- 有
watch或watchEffect监听myData或datasets[0].data,且回调中再次调用handleCurrency形成无限循环 - 模板中对
datasets[0].data的循环渲染逻辑,间接修改了该数组
内容的提问来源于stack exchange,提问作者May W.
相关产品推荐
相关产品推荐

