amedina
amedina

Reputation: 3426

Vue: Make a child component be aware of a change in a property modified by its parent

I have a child component that's basically a search box. When the user types something and presses enter, an event is fired that goes to the parent with the search topic:

export default {
  name: "SearchBar",
  methods: {
    searchRequested(event) {
      const topic = event.target.value;
      this.$emit('searchRequested', topic);
    }
  }
};

The parent receives the event and updates a prop connected to other of its children (an image gallery):

<template>
  <div id="app">

    <SearchBar @searchRequested="onSearchRequested($event)" />
    <Images :topic="topic" />

  </div>
</template>

<script>
import SearchBar from './components/SearchBar.vue'
import Images from './components/Images.vue'

export default {
  name: 'app',
  components: {
    SearchBar,
    Images
  },
  data() {
    return {
      topic: ''
    };
  },
  methods: {
    onSearchRequested(topic) {
      this.topic = topic;
    }
  }
}
</script>

So far, so good. But now I want the child component load itself with images related to the searched topic whenever the user performs a new search. For that, the child component Images must be aware of a change on its property topic, so I created a computed one:

import { ImagesService } from '../services/images.service.js';

export default {
  data() {
    return {
      topic_: ''
    };
  },
  methods: {
    updateImages() {
      const images = new ImagesService();
      images.getImages(this.topic_).then(rawImages => console.log(rawImages));
    }
  },
  computed: {
    topic: {
      get: function() {
        return this.topic_;
      },
      set: function(topic) {
        this.topic_ = topic;
        this.updateImages();
      }
    }
  }
};

But unfortunately, the setter never gets called. I have to say I'm new in Vue, so probably I'm doing something wrong. Any help will be appreciated.

Upvotes: 1

Views: 620

Answers (1)

elad frizi
elad frizi

Reputation: 725

You don't need to create computed in the main component. Images component is already aware of the changes in the topic prop. You need to watch the changes of topic and do an async operation in 'Images.vue'. It's possible with Vue's watchers.

Vue docs watchers

'./components/Images.vue'

<template>...</template>
<script>
export defult {
 props: ['topic'],
 data(){
   return {
        images: []
    }
 },
 watch: {
    topic(newVal){
       // do async opreation and update data.
       // ImageSerice.get(newVal)
       //   .then(images => this.images = images)
     }
  }
}
</script>

Upvotes: 2

Related Questions