Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

223
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!