alex
alex

Reputation: 7601

How to make an Object with spread (...) notation reactive?

I'm trying to change the opacity attribute of an object and make that change reactive:

Component.vue:

<child-component :common="itemCommon"></child-component>

<script>
data () {
  return {
    rest: {}
  }
},

computed: {
  itemCommon () {
    return {
      item: {
        opacity: 1,
        ...this.rest
      }
    }
  }
},

beforeMount () {
  this.rest = { name: 'a' }
}
<script>

childComponent.vue:

<script>
props: {
  common: {
    type: Object,
    default () {
      return {}
    }
  }
},

beforeMount () {
  this.common.item.opacity = 0
}
</script>

The opacity attribute won't be set to 0. Vue doesn't consider itemCommon

How to modify the code so itemCommon becomes reactive?

Upvotes: 0

Views: 110

Answers (1)

JJPandari
JJPandari

Reputation: 3522

Generally, vue watches the changes on components' data properties, and change the view when it sees a data change. So to make some data reactive, we have to declare it in a component's data. You don't have opacity in either component here, so it's probably not picked up by vue. Adding it to the parent's data should fix it, but you'll get a warning like directly setting prop in child, then you should move this.common.item.opacity = 0 to the parent. You can find plenty searching the warning but here briefly: prop will commonly be changed in the parent, changing it also in the child is confusing, and by design, the child provides functionality/interface, the parent, who makes use of the child, give data to the child in runtime, trusting the child handling the data with the functionality we expect, so we achieve loose coupling. (this is also usually called a one-way data flow)

Upvotes: 1

Related Questions