VueJS увеличивает все пять изображений одновременно

#javascript #vue.js

#javascript #vue.js

Вопрос:

Я хочу увеличивать изображения одно за другим. Но этот код прямо сейчас работает следующим образом: я нажимаю на изображение и увеличиваю все пять изображений одновременно, а затем после другого щелчка все они уменьшаются. Как это исправить, чтобы я мог масштабировать их одно за другим?

        <img src="/images/{{advertisement.img}}" class="mr-3" :style="{ width: imageWidth   'px', height: imageHeight   'px' }"
        @click="toggleZoom">

        <img src="/images/{{advertisement.img2}}" class="mr-3" :style="{ width: imageWidth   'px', height: imageHeight   'px' }"
        @click="toggleZoom">

        <img src="/images/{{advertisement.img3}}" class="mr-3" :style="{ width: imageWidth   'px', height: imageHeight   'px' }"
        @click="toggleZoom">

        <img src="/images/{{advertisement.img4}}" class="mr-3" :style="{ width: imageWidth   'px', height: imageHeight   'px' }"
        @click="toggleZoom">

        <img src="/images/{{advertisement.img5}}" class="mr-3" :style="{ width: imageWidth   'px', height: imageHeight   'px' }"
        @click="toggleZoom">
  

Часть VueJS.

    new Vue({
        el: '#advertisementManagement', 
        data: {
            isZoomed: false,
            imageWidth: '',
            imageHeight: ''
        },
        methods: {
            zoomIn() {
                this.isZoomed = true;
                this.imageWidth = 300;
                this.imageHeight = 300;              
            },
            zoomOut() {
                this.isZoomed = false;
                this.imageWidth = 100;
                this.imageHeight = 100;                 
            }
        },
        computed: {
        toggleZoom() {
            return this.isZoomed ? this.zoomOut : this.zoomIn;
            }         
        }        
    });
  

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

1. Является advertisement частью вашего data ?

2. Вы используете imageWidth и imageHeight вашего компонента для каждого изображения. Затем, щелкнув по одному, вы устанавливаете компоненты imageWidth и imageHeight — все они изменяют размер. Он делает именно то, что вы просите.

3. @Terry Да. Я получаю изображения из базы данных,

4. @RandyCasburn Итак, для каждого изображения мне нужно создать новый метод?

5. Как минимум, вам нужно воздействовать на каждое изображение по отдельности. Значение: высота и ширина каждого изображения должны быть изменены индивидуально. Скорее всего, самым простым подходом было бы использовать цель события.

Ответ №1:

Вам придется абстрагировать их от отдельных компонентов или, по крайней мере, объявить состояние масштабирования для каждого отдельного изображения. Это потому, что this.isZoomed состояние сохраняется на уровне приложения, где находятся все изображения, что означает, что каждое изображение не сохраняет свое отдельное увеличенное состояние.

VueJS чрезвычайно упрощает атомарный дизайн: в этом случае ваше рекламное изображение является атомарным компонентом, поскольку оно должно обрабатывать свое собственное состояние. Это можно сделать, скажем, создав пользовательский компонент, который будет отслеживать индивидуальное <ad-image> состояние изображения, а также его размеры………..». isZoomed :

 Vue.component('ad-image', {
  template: '#ad-image',
  props: {
    src: {
      type: String,
      required: true
    }
  },
  data: function() {
    return {
      width: 300,
      height: 300,
      isZoomed: false
    }
  },
  methods: {
    zoomIn() {
      this.isZoomed = true;
      this.width = 300;
      this.height = 300;
    },
    zoomOut() {
      this.isZoomed = false;
      this.width = 100;
      this.height = 100;
    }
  },
  computed: {
    toggleZoom() {
      return this.isZoomed ? this.zoomOut : this.zoomIn;
    }
  }
});

new Vue({
  el: '#advertisementManagement',
  data: {
    advertisement: {
      img: 'https://via.placeholder.com/300x300',
      img2: 'https://via.placeholder.com/300x300',
      img3: 'https://via.placeholder.com/300x300',
      img4: 'https://via.placeholder.com/300x300'
    }
  }
});  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="advertisementManagement">
  <ad-image :src="advertisement.img" />
  <ad-image :src="advertisement.img2" />
  <ad-image :src="advertisement.img3" />
  <ad-image :src="advertisement.img4" />
</div>

<script type="text/x-template" id="ad-image">
  <img :src="src" class="mr-3" :style="{ width: width   'px', height: height   'px' }" @click="toggleZoom" />
</script>  

Полезный совет: вы можете абстрагировать все привязки стилей в вычисляемое свойство, чтобы не загромождать свой шаблон VueJS интерполяциями строк и конкатенациями:

 <img :src="src" class="mr-3" :style="styleObject" @click="toggleZoom" />
  

А затем в вашей логике JS:

 computed: {
  toggleZoom() {
    return this.isZoomed ? this.zoomOut : this.zoomIn;
  },
  styleObject() {
    return {
        width: width   'px',
        height: height   'px'
    };
  }
}
  

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

1. Но почему это показывает только первое img , а не все пять?