What is the correct way to change the data of an already mounted component?

Viewed 419

I am learning vue2 and came across this scenario. I render a component that contains a list of items, when I click on any of these items, another component is shown with the item's detail. When the detail component is created in the created hook, I call an api to obtain the detail data. So far so good. My problem is that after clicking on another item, the detail does not change its data. I understand it is because the created hook is not called again.

I have tried the updated, beforeUpdate hooks but in both cases I get a bad behavior I guess it is because they call the same fetchDetail method. Another solution that I thought was that before passing to the selectedItem state property in the new selected item, pass it an empty value {} to cause the component to be rendered. But without success

Data from parent component

data {
  selectedItem: {}
}

Method in parent component

displayDetailHandler({ id, title }) {
  this.selectedItem = {}; // intro provocar rerender
  this.selectedItem = { id, title };
}

Call to child component

<template v-if="Object.keys(selectedItem).length > 0">
  <Detail :item="selectedItem"></Detail>
</template>

Child component created hook

created() {
  this.fetchGameDays(); // call to api
}

What is the correct way to change the data of an already mounted component?

2 Answers

Use a watch on the changing prop (in your case, on item's id):

watch: {
  'item.id': {
    handler(id) {
      if (id) {
        // call API, using the id
      }
    },
    immediate: true /* makes it run immediately after you set the watcher,
                     * does not wait until first change (like `created` call) */
  }
}

Besides, you probably want to nullify child data when the child component is closed, so the second time you open it it doesn't display the old data while the new API call is fetching.

As a side note, v-if="Object.keys(selectedItem).length > 0" can be simplfied to
v-if="selectedItem.id"

You can use watch in vuejs It is basically a function that will be called every time there is a change it the data that is being watched. So sometime if it is a complex object that you are watching then you might need to use deep:true in the watch properties.

Related