Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

232
Visualizações
Prevent computed with other computed as dependency from re-computing when actual value does not change

I am trying to achieve something quite tricky regarding usage of multiple inter-dependent computed properties.

My initial question is the following : We have a computed value A and a computed value B. B has A as a dependency. Now, the dependencies of A changes, but the output value is still the same, so it's recomputed but returns the same value.

From what I've found out on my investigation, even if the output value of A does not change, if A is re-computed, then B will abso be re-computed. I want to know if there is a way to achieve this behaviour

To provide you context, let me first give you a concrete example that's close enough to my real use case :

<script setup>
  import { ref, reactive, computed } from 'vue';

  const formState = reactive({
    field1: '',
    field2: {
      field2Child: 'MyChildVal',
    },
  });

  const mapDependencies = (arrayDependencies) => {
    let dependencies = {};
    for (const { key, value } of arrayDependencies) dependencies[key] = value;
    return dependencies;
  };

  const resolveFromString = (path, obj, separator = '.') => {
    var properties = Array.isArray(path) ? path : path.split(separator);
    return properties.reduce((prev, curr) => prev && prev[curr], obj);
  };

  const listDependencies = ['field2.field2Child'];

  // Will re-render every time formState changes
  const dependencies = computed(() =>
    mapDependencies(
      listDependencies.map((key) => ({
        key,
        value: resolveFromString(key, Object.assign({}, formState)),
      }))
    )
  );
  
  const dependenciesAsString = (dependencies) => {
    return 'The dependencies are' + Object.entries(dependencies).map(([key, value]) => `${key} : ${value}`);
  }

  // Expected to re-render only when the output of "dependencies" changes. But on real usage
  const computedBasedOnDependencies = computed(() => dependenciesAsString(Object.assign({}, dependencies.value)));

  const ChangeState = () => formState.field1 = new Date().toString(); 
</script>

I created a live reproduction of this of stackblitz : https://stackblitz.com/edit/vue-svtsu2?file=src/App.vue

The behaviour I expected from this : If the output of "dependencies" does not change, then the timestamp at the begining of "computedBasedOnDependencies" should not change

The behaviour I get : Even when "dependencies" output is not changing, when it's re-computed "computedBasedOnDependencies" is recomputed as well

If you have any insight about something I don't understand correctly from Vue reactivity, or any other way to achieve this behaviour, I welcome any help whatsoever.

Thanks by advance !

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Computed property functions are supposed to be pure functions, i.e. they don't make side effects, and function output depends only on input.

For any other logic, a watcher should be used. This is the case for a watcher, where can be throttled with either source function and/or a comparison of old and new value:

const computedBasedOnDependencies = ref(null);

watch(
  () => stringifyWithoutTimestamp(dependencies.value)),
  (val, oldVal) => {
    if (val !== oldVal)
      computedBasedOnDependencies.value = stringifyWithTimestamp(dependencies.value);
  },
  { immediate: true }
);
over 4 years ago · Santiago Trujillo Relatório

0

Even when "dependencies" output is not changing...

Well problem is it is changing - even if it returns the object with the same content as before, it is still a new object

function getObject() {
  return { value: "A" }
}

const a = getObject()
const b = getObject()

console.log(a === b)

Vue does not do "deep" comparison as that would be a major performance hit (the value returned from computed can be anything - deeply nested object for example). SO if you need this, you must implement it yourself presumably using watch instead of computed

But before going that route you should be sure that what you are doing is not just a premature optimization

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda