1

I have two Vue components, EventTask and EventCard. EventTask has a currentEvent object in data, which I pass as a prop to EventCard like so

<event-card :current-event="currentEvent" />

In EventCard, I initialise an event data property from the currentEvent prop, as suggested in this answer

export default {
  name: 'EventCard',
  props: {
    currentEvent: {
      type: Object,
      required: false
    }
  },
  data: function () {
    return {
      event: { ...this.currentEvent }
    }
  }
}

However, for some reason, the event data property is not being set correctly. Here's what I see in the Vue developer tools

enter image description here

Notice that the currentEvent prop is an object with a with a bunch of properties, but the event data property is an empty object. Why is the data property not being initialised correctly from the prop?

tony19
  • 125,647
  • 18
  • 229
  • 307
Dónal
  • 185,044
  • 174
  • 569
  • 824
  • 1
    Can you share a simple demo/fiddle representing your scenario, because it works in normal cases. – Majed Badawi Jul 30 '20 at 19:07
  • why do you need to create another property in data? you can use the same currentEvent (this.currentEvent) in your EventCard component. Any specific reason for creating another property in data?. The other way is to assign the currentEvent to event (in data) in one of the life cycles, you can use mounted() {this.event = this.currentEvent } – Sowmyadhar Gourishetty Jul 30 '20 at 19:11
  • @SowmyadharGourishetty I need to create another property in data because I will be modifying this object in the `EventCard` component, but I don't want these changes to propogate to the `EventTask` component – Dónal Jul 30 '20 at 19:21

3 Answers3

2

This can occur if currentEvent is updated after EventCard has already initialized. Note that data() is not invoked reactively, so changes to currentEvent would not re-initialize event.

One solution is to use a watcher on currentEvent to copy it to event:

export default {
  watch: {
    currentEvent(newValue) {
      this.event = { ...newValue }
    }
  }
}

demo

tony19
  • 125,647
  • 18
  • 229
  • 307
  • I think `currentEvent` being updated after `EventCard` has initialized is exactly what the problem is. I didn't realise that `data()` is invoked only once, rather than reactively. – Dónal Jul 30 '20 at 20:48
0

you can try the below code

export default {
  name: 'EventCard',
  props: {
    currentEvent: {
      type: Object,
      required: false
    }
  },
  data: function () {
    return {
      event: null
    }
  },
  mounted () {
    this.event = this.currentEvent // you can also try clone here.
  }
}
Sowmyadhar Gourishetty
  • 1,843
  • 1
  • 8
  • 15
0

Try doing it like this instead:

export default {
  name: 'EventCard',
  props: {
    currentEvent: {
      type: Object,
      required: false
    }
  },
  data: function () {
    return {
      event: this.currentEvent
    }
  }
}

Source : https://v2.vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow

tony19
  • 125,647
  • 18
  • 229
  • 307
Samy Kacimi
  • 1,216
  • 9
  • 23
  • 2
    AFAIK, it's recommended that you *don't* do this when the prop is an object or array (which are passed by reference), because changes in the child will also be reflected in the parent. Source https://stackoverflow.com/a/40435856/2648 – Dónal Jul 30 '20 at 20:47
  • Okay! Thanks for the info – Samy Kacimi Jul 30 '20 at 21:20