Roman Khlebnikov
Roman Khlebnikov

Reputation: 37

Popup does not open in App.vue when clicking on a search result

My goal is when clicking on any search item to open the Popup. Why does not work — this.$emit('openPopup', bookId); in the method selectBook(bookId)

There is a component of Results.vue, which displays search results by using Google Books API:

<template>
  <div class="results">
    <ul class="results-items">
      <li
        class="book"
        @click="selectBook(result.id)"
      >
        <img
          :src="'http://books.google.com/books/content?id=' + result.id + '&printsec=frontcover&img=1&zoom=1&source=gbs_api'"
          class="cover"
        >
        <div class="item-info">
          <div class="bTitle">{{ result.volumeInfo.title }}</div>
          <div
            class="bAutors"
            v-if="result.volumeInfo.authors"
          >
            {{ result.volumeInfo.authors[0] }}
          </div>
        </div>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  props: ['result'],
  data() {
    return {
      bookId: '',
    };
  },
  methods: {
    selectBook(bookId) {
      this.$router.push(`bookId${bookId}`);
      this.$store.dispatch('selectBook', bookId);
      this.$emit('hideElements', bookId);
      this.$emit('openPopup', bookId);
    },
  },
};
</script>

Rusults screenshot

Is the main App.vue, which I want to display Popup:

<template>
  <div id="app">
    <div class="container">
      <Header />
      <popup
        v-if="isOpenPopup"
        @closePopup="closeInfoPopup"
        @openPopup="showModal"
      />
      <router-view/>
    </div>
  </div>
</template>

<script>
import Header from '@/components/Header.vue';
import Popup from '@/components/Popup.vue';
import 'bootstrap/dist/css/bootstrap.css';

export default {
  components: {
    Header,
    Popup,
  },
  data() {
    return {
      isOpenPopup: false,
    };
  },
  methods: {
    showModal() {
      console.log('click');
      this.isOpenPopup = true;
    },
    closeInfoPopup() {
      this.isOpenPopup = false;
    },
  },
};
</script>

The component Popup.vue

<template>
  <div class="popup">
    <div class="popup_header">
      <span>Popup name</span>
    </div>
    <div class="popup_content">
        <h1>Hi</h1>
      <slot></slot>
      <button @click="closePopup">Close</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'popup',
  props: {},
  data() {
    return {};
  },
  methods: {
    closePopup() {
      this.$emit('closePopup');
    },
  },
};
</script>

Upvotes: 1

Views: 526

Answers (1)

farincz
farincz

Reputation: 5173

You are listening on popup component but triggering events on Result Don't remember that events are bound to component.

You have several options how to handle it

  1. Add event listeners (like @openPopup) only on Result component and use portal-vue library to render popup on top level
  2. use global events, this.$root.emit and listen also on this.$root. In this case you add event listener in mount() hook and don't forget unregister it in beforeDestroy() hook
  3. you can use Vuex and popup visibility and related data in global application store provided by Vuex

Upvotes: 1

Related Questions