filur
filur

Reputation: 1556

Computed property based on child components

Is it possible to create a computed property that relies on child components data? Seems like a trivial task but I can't figure it out...

foo component

<template>
    {{ foo }}
</template>

<script>
export default { 
    computed: {
        foo() {
            return Math.random()
        }
    }
}
</script>

parent component

<template>
    foo computed property sum: {{ sum }}
    <Foo v-for="n in 10"></Foo>
</template>

export default { 
    computed: {
        sum() {
            // return...?            
        }
    }
}
</script>

Upvotes: 3

Views: 3061

Answers (1)

Roy J
Roy J

Reputation: 43881

You can, but it's a pretty unusual approach to things, so it's likely not the best choice for whatever you're trying to achieve.

Instead, you might keep the data in the parent and pass it to the component as a prop. If you use value as the prop name, you can get some nice clean syntax from v-model. (You have to use foos[index] due to the fact that you can't v-model an alias, but in this case you're just generating an index anyway).

new Vue({
  el: '#app',
  data: {
    foos: []
  },
  computed: {
    sum() {
      return this.foos.reduce((a, b) => a + b, 0);
    }
  },
  components: {
    Foo: {
      template: '<div>{{ value }} <button @click="reroll">Change it</button></div>',
      props: ['value'],
      created() {
        this.reroll();
      },
      methods: {
        reroll() {
          this.$emit('input', Math.floor(Math.random() * 10));
        }
      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  foo computed property sum: {{ sum }}
  <Foo v-for="index in 10" v-model="foos[index]"></Foo>
</div>

Upvotes: 4

Related Questions