Отображение выбранного изображения в модальном

#javascript #vue.js

#javascript #vue.js

Вопрос:

Я создал простое приложение, используя Vue.js где пользователи могут просматривать книги, выбирая имена авторов. Затем я добавил модал для отображения книг, однако каждый раз, когда я нажимаю на разные карточки, он продолжает показывать одно и то же изображение. Я попытался выполнить цикл и использовал следующий код:

     <div class="modal" v-for="item in card">
        <img v-bind:src="item.img" class="book-enlarge" alt="book" />
    </div>
 

Вот мой HTML-код:

     <div
        v-show="author === '' || author === item.author"
        :class="{ active: author === item.author }"
        v-for="(item, index) in card"
        v-bind:data-index="index   1"
        @click="showModal(index)"
    >
        <img v-bind:src="item.img" alt="book" class="card__book" />
        <div class="card__body">
            <h1 class="card__title">{{ item.title }}</h1>
            <p class="card__author">
                <span class="card__author--mod">By:</span>
                {{ item.author }}
            </p>
            <p class="card__release">
                <span class="card__release--mod">Release Date:</span>
                {{ item.release }}
            </p>
        </div>

        <form v-bind:action="item.link" target="_blank">
            <input class="btn" type="submit" value="Buy on Amazon" />
        </form>
    </div>

    <div class="overlay" id="overlay">
        <div ref="close" @click="close" class="overlay__close">
            amp;#8855;
        </div>
        <div class="modal" v-for="item in card">
            <img v-bind:src="item.img" class="book-enlarge" alt="book" />
        </div>
    </div>
 

Вот мой Vue.js код:

 const cardDescriptions = [
  {
    img: `../books-img/book-1.jpg`,
    title: `A Life on Our Planet: My Witness Statement and a Vision for the Future`,
    author: `David Attenborough`,
    release: `2020-10-01`,
    link: `https://www.amazon.co.uk/Life-Our-Planet-Witness-Statement/dp/1529108276/ref=sr_1_1?dchild=1amp;keywords=a life on our planetamp;qid=1610306225amp;quartzVehicle=45-608amp;replacementKeywords=a on our planetamp;sr=8-1`,
  },
  {
    img: `../books-img/book-2.jpg`,
    title: `Life on Air`,
    author: `David Attenborough`,
    release: `2010-05-20`,
    link: `https://www.amazon.co.uk/Life-Air-David-Attenborough/dp/1849900019/ref=sr_1_1?dchild=1amp;keywords=life on airamp;qid=1610306334amp;quartzVehicle=45-608amp;replacementKeywords=on airamp;sr=8-1`,
  },
  {
    img: `../books-img/book-3.jpg`,
    title: `HTML, CSS and JavaScript in easy steps`,
    author: `Mike McGrath`,
    release: `2020-08-06`,
    link: `https://www.amazon.co.uk/HTML-CSS-JavaScript-easy-steps/dp/184078878X/ref=sr_1_1?dchild=1amp;keywords=HTML, CSS and JavaScript in easy steps: (In Easy Steps)amp;qid=1610306384amp;sr=8-1`,
  },
  {
    img: `../books-img/book-4.jpg`,
    title: `HTML5 in easy steps, 2nd edition`,
    author: `Mike McGrath`,
    release: `2017-02-17`,
    link: `https://www.amazon.co.uk/HTML5-easy-steps-Mike-McGrath/dp/1840787546/ref=sr_1_1?dchild=1amp;keywords=HTML5 in easy steps: (2nd edition)amp;qid=1610306431amp;sr=8-1`,
  },
];

new Vue({
  el: '#container',
  data: {
    card: cardDescriptions,
    author: '',
  },
  methods: {
    displayBooks: function (e) {
      this.author = e.target.value;
    },
    showModal: function (index) {
      document.querySelector('#overlay').style.display = 'block';
      console.log(index   1);
    },
  },
  computed: {
    filteredNames: function () {
      const authors = [];
      this.card.forEach(item => {
        if (!authors.includes(item.author)) {
          authors.push(item.author);
        }
      });
      return authors;
    },
  },
});

new Vue({
  el: '#overlay',
  data: {
    card: cardDescriptions,
  },
  methods: {
    close: function () {
      const closeModal = this.$refs.close.parentNode;
      closeModal.style.display = 'none';
    },
  },
});
 

Любая помощь будет с благодарностью!

Спасибо!

Комментарии:

1. Вместо использования компонентов вы запускаете два приложения. У вас должен быть только один вызов new Vue , и все должно быть внутри одного div, где смонтировано приложение.

2. Привет, @Dan, спасибо за ваш ответ. Я попытался реализовать ваше решение, но оно по-прежнему отображает то же изображение.

3. Привет, Рабин, я не дал решения. Было бы лучше отредактировать ваш вопрос, чтобы показать, что вы пытались в ответ на мой комментарий

4. Я удалил второй экземпляр Vue и переместил modal внутрь <div> контейнера, в котором смонтировано приложение. Затем я использовал a for loops для перебора изображений.

Ответ №1:

Ваш пример по-прежнему показывает два экземпляра Vue.

Вам нужно использовать require примерно так:

     <img v-bind:src="require`@/assets/${item.img}`" alt="book" class="card__book" />
 

@ это корень вашей src папки, и вам нужно указать некоторую статическую строку для вашего запроса, чтобы она работала.

Кроме того, вам необходимо указать свой v-for key , чтобы vue мог идентифицировать уникальные элементы

     <div class="modal" v-for="(item, index) in card" :key="index">
        <img v-bind:src="item.img" class="book-enlarge" alt="book" />
    </div>