Use computed property in data in Vuejs

Viewed 29371

How can I use a computed property in the data or emit it via bus?

I have the following vue instance, but myComputed is always undefined but computedData is working correctly.

var vm = new Vue({
  data(){
    return{
      myComputed: this.computedData
    }
  },

  computed: {
    computedData(){
      return 'Hello World'
    }
  }
})
8 Answers

Unfortunately, it is impossible to use computed property in data because of component creation timing: data evaluates Before computed properties.

  1. Computed is already accessible in the template using {{ }}.

  2. But you can use the

watch:{
  //your function here
}

instead of computed

If you are using computed/reactive objects then it should be inside the computed and not inside the data.

Simply change your code to use computed instead of data

var vm = new Vue({
  data(){
    return{}
  },

  computed: {
    computedData(){
      return 'Hello World'
    },
    myComputed(){
     return this.computedData
    }
  }
})

you are trying to use data as computed and this shall not be. data doesn't act like computed object.

and it's not because of component creation timing. What if we changed the component creation timing ? this will not solve anything as data will take only the first computed value(only one) and will not update after.

you can work just with the computed function

   var vm = new Vue({
      data(){
        return{
          //is not necessary
        }
      },
    
      computed: {
        computedData(){
          return 'Hello World'
        }
      }
    })

and in your template

<template>
  <div>{{ computedData }}</div>
</template>

You are over-coding it. Computed props are accessible in the same manner as data props in your template.

var vm = new Vue({
  computed: {
    myComputed(){
      return 'Hello World'
    }
  }
})

In the template you have access to this just like you do to data:

<template>
  <div>{{ myComputed }}</div>
</template>

https://v2.vuejs.org/v2/guide/computed.html

computed is not available at the time data gets initialized.

If it should be a one-time thing (and NOT reactive), you could achieve this by setting the data at the moment where the computed property is available by using the created() hook:



export default {
  data: () => ({
    myDataBackend: '',
  }),
  computed: {
    computedData () {
      return 'Hello World'
    }
  },
  created() {
    this.$set(this, 'myDataBackend', this.computedData)
  }
}

Futher reading: Vue Documentation on Lifecycle Hooks


In case you are trying to work with v-model:

You could also use :value and some event like @change or @keyup in the element instead.

  • :value is the value which the input-element initially works with
  • After writing some letter in the input field, the @keyup event changes the data.
    Typically, events carry the updated form value in target.value
  • The changeMyData method sets the value
  • the computed property listens to the data change and the :value of the input field gets updated.

Note: I used data as a data store. But you could also use for example vuex instead.

<template>
<div>
  <input
    type="text"
    :value="computedData"
    @keyup="changeMyData"
  />
  <p>{{myDataBackend}}</p>
</div>
</template>

<script>

export default {
  data: () => ({
    myDataBackend: 'Hello World'
  }),
  methods: {
    changeMyData(evt) {
        this.$set(this, 'myDataBackend', evt.target.value)
        console.log('Changed the value to: ' + evt.target.value)
    }
  },
  computed: {
    computedData () {
      return this.myDataBackend
    }
  }
}
</script>
Related