计算属性或普通函数做复杂的计算操作时,代码中有对相关依赖的响应式数据进行更新就可能导致函数反复执行,达到最大执行限制。

const calcSurplus = computed(() => (k: string) => {
  const nowMont = cashbook.value[year.value][k];
  let isFirstMonth = false;
  let expenses = 0;
  let surplus = 0;

  nowMont.outlays?.forEach(ele => {
    expenses += Number(ele.cost);
  });

  montKs.forEach((ele, index) => {
    if (k == ele && index == 0) {
      isFirstMonth = true;
    }
  });

  surplus = Number(nowMont.budget) - expenses;

  if (!isFirstMonth) {
    const nowK = montKs.findIndex(ele => ele == k);
    const preMont = cashbook.value[year.value][montKs[nowK - 1]];
    if (preMont?.surplus && nowMont?.budget) {
      surplus = Number(nowMont.budget) - expenses + Number(preMont.surplus);
    }
  }

  nowMont.surplus = surplus;
  // here =>
  nowMont.budget = surplus;

  return surplus;
});

问题在上述代码注释下的一行代码。这里有两个更改响应式数据的表达式,如果我不加第二个,不会出现标题中说的问题,如果加了第二个就会。

在模板中使用了 calcSurplus 计算属性。修改对象 surplus 属性,页面 DOM 更新、重新渲染,此时,又接着修改 budget 属性,页面 DOM 又更新、又重新渲染,因此出现 Maximum recursive updates exceeded. 警告。

综上所述,在使用计算属性,修改一个以上的响应式数据时,要注意不出现上述代码的问题。