0

当计算值依赖于一个引用依赖于另一个引用的多个引用时,对于计算值仅触发一次昂贵的重新计算的最佳实践是什么?

例子:

在以下设置中,我只想expensiveData计算一次。expensiveDatavarAvarB变化时重新计算,但又varBvarA. 所以当varA改变时,varB也必然会改变。

import { ref, watch } from '@vue/composition-api';

// varA is calculated from fetched data
// and updated when the data changes
const varA = ref([
  /* some data */
]);

// varB is data that is derived from varA, but user
// can independently modify varB without changing varA
const varB = ref(null);

// Derive varB from the varA's value
const updateVarB = (a) => {
  const varBValue = /* process varA */;
  varB.value = varBValue
};

// When varA changes, change varB too.
watch(varA, (newVarA) => {
  updateVarB(newVarA);
});

export { varA, varB, updateVarB }

some-other-file.js

...
// value of varB is changed upon user-triggered event
const someData = ...
updateVarB(someData);

expensive-calc.js

import { computed, toRefs } from '@vue/composition-api';
...
/* varA and varB are passed as props */
const { varA, varB } = toRefs(props);

const makeExpensiveData = (...args) => /* some heavy lifting */

const expensiveData = computed(() => {
  /* some calculations with varA and varB */
  return makeExpensiveData(varA.value, varB.value)
});

有哪些可能的方法来处理这种情况,以便expensiveData只重新计算一次?

注意事项:

  • varA并且varB在语义上是不同的,因此创建一个将它们捆绑在一起的新计算值不太有意义。

当前的解决方案是消除对makeExpensiveDatawith的调用lodash.debounce。由于varB派生自varA,因此它们会同时触发重新计算。

但是,我对 Vue 的组合 API 比较陌生,所以我想知道是否有更好的方法来处理这个问题。

4

1 回答 1

0

如果varB保证在更新后始终更新varA,则可以将 a 替换为computedaref和 a watch

const expensiveData = ref(null);

watch(
  varB,
  () => expensiveData.value = makeExpensiveData(varA.value, varB.value),
  { immediate: true } // <- if you want to access it immediately
);

无论如何,这仍然可以重现吗?

于 2020-09-20T07:33:50.443 回答