Home > Software design >  Why is Javascript object property set to initial value of Vue computed property?
Why is Javascript object property set to initial value of Vue computed property?

Time:09-03

Can somebody help me understand why the javascript object property, data.test, is always set to the initial value of the computed property, square? When clicking submit after entering a number in the input field, you will see that data.test is always equal to 4; however, the computed property is working properly as confirmed by the html elements, anyNum and square; those elements show that Vue reactivity is working properly.

Here's the fiddle

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

const anyNum = ref(2)

const square = computed(() => {
  return anyNum.value * anyNum.value
})

const data = {    
  test: square.value <===== Javascript object property is always equal to 4
}

function submitForm() {
  console.log(data)
}    
</script>

<template>
  <p>anyNum: {{ anyNum }} </p>
  <p>square: {{square}} </p>
  <form>    
      <input v-model="anyNum" type="number" >
      <button @click.prevent="submitForm()">
        Submit
      </button>
  </form>
</template>

But, if I change the javascript object data to a function, then data.test captures the computed value of squared. Here's the fiddle.

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

const anyNum = ref(2)

const square = computed(() => {
  return anyNum.value * anyNum.value
})

const data = () => { 
  return {
    test: square.value  <===== captures the value correct value
  }
}

function submitForm() {
  console.log(data())
}
</script>

CodePudding user response:

data.test is not being reactively updated based on any UI changes. It has it's initial value set on component creation and is then never updated again. It's not keeping track of "live" data. If you want data.test to recalculate based on square.value changing then data will also need to be a computed property:

const data = computed(() => { 
  return { test: square.value }
})

the reason your second example works is because as a function it will always rerun/recalculate whenever it's actively called

CodePudding user response:

I suggest that you read Reactivity in Depth page of Vue documentation. According to that:

When you assign or destructure a reactive object's property to a local variable, the reactivity is "disconnected" because access to the local variable no longer triggers the get / set proxy traps.

So because the data variable is a local variable and you did not used ref or reactive for that, It behaves like normal JavaScript. Do you expect reactivity from normal JS?

  • Related