Поэтому я загружаю, просматриваю и удаляю несколько изображений в vue js. Вот что у меня есть:

<input id="file-upload" type="file" multiple @change="uploadImage" />
<div v-for="(image, key) in productImages" :key="key">
  <div class="image-holder">
    <img v-bind:ref="'image'" alt="" src="" />
    <button type="button" @click="removeImage(image, key)"></button>
  </div>
</div

uploadImage(e) {
    let selectedFiles = e.target.files;
    for (let i = 0; i < selectedFiles.length; i++) {
          this.productImages.push(selectedFiles[i]);
    }
    for (let i = 0; i < this.productImages.length; i++) {
       let reader = new FileReader();
       reader.onload = (e) => {
          this.$refs.image[i].src = reader.result;
       };
       reader.readAsDataURL(this.productImages[i]);
       }
     },

removeImage(image, index) {
   this.productImages.splice(this.productImages.indexOf(image),1);
   this.$refs.image[index].src = ""
},

Но вот в чем проблема: например, я загружаю три изображения и нажимаю, чтобы удалить второе изображение (посередине), но оно удаляет изображение посередине (которое я щелкнул) и последнее изображение (которое я не нажимал) удалять). Таким образом, в основном одним щелчком мыши удаляются два изображения.

Любые предложения, как это исправить?

1
Edga 17 Сен 2021 в 20:46

3 ответа

Лучший ответ

Вы скрываете третий после нарезки массива.

Индекс перед срезом 0 1 2

Индекс после среза 0 1

2 становятся 1 в массиве. Просто попробуйте прокомментировать последнюю строчку

Edit: И изображение по-прежнему привязано к index. Поэтому я просто переписываю код:

<template>
  <div id="app">
    <input id="file-upload" type="file" multiple @change="uploadImage" />
    <div v-for="(image, key) in productImages" :key="key">
      <div class="image-holder">
        <img v-bind:ref="'image'" alt="" src="" />
        <button type="button" @click="removeImage(image, key)">x</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  components: {},
  data() {
    return {
      productImages: [],
    };
  },
  methods: {
    uploadImage(e) {
      let selectedFiles = e.target.files;
      for (let i = 0; i < selectedFiles.length; i++) {
        this.productImages.push(selectedFiles[i]);
      }
      this.applyImage();
    },

    removeImage(image, index) {
      console.log(this.productImages);
      this.productImages.splice(index, 1);
      this.applyImage();
      //this.$refs.image[index].src = "" // You are hidding the 3rd one that is now in index 1.
    },
    applyImage() {
      for (let i = 0; i < this.productImages.length; i++) {
        let reader = new FileReader();
        reader.onload = (e) => {
          this.$refs.image[i].src = reader.result;
        };
        reader.readAsDataURL(this.productImages[i]);
      }
    },
  },
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.image-holder {
  float: left;
}
</style>
1
Patfreeze 17 Сен 2021 в 20:01

Попробуйте вызвать метод рендеринга изображений:

new Vue({
  el: '#demo',
  data() {
    return {
      productImages: []
    }
  },
  methods: {
    uploadImage(e) {
      let selectedFiles = e.target.files;
      for (let i = 0; i < selectedFiles.length; i++) {
        this.productImages.push(selectedFiles[i]);
      }
      this.refreshImg()
    },
    refreshImg() {
      for (let i = 0; i < this.productImages.length; i++) {
        let reader = new FileReader();
        reader.onload = (e) => {
          this.$refs.image[i].src = reader.result;
        };
        reader.readAsDataURL(this.productImages[i]);
      }
    },
    removeImage(image, index) {
      this.productImages.splice(index, 1);
      this.refreshImg()
    },
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<template>
  <input id="file-upload" type="file" multiple @change="uploadImage" />
  <div v-for="(image, key) in productImages" :key="key">
    <div class="image-holder">
      <img v-bind:ref="'image'" alt="" src="" style="width: 50px;" />
      <button type="button" @click="removeImage(image, key)"></button>
    </div>
  </div>
  </template>
</div>
1
Nikola Pavicevic 17 Сен 2021 в 20:13

На самом деле при использовании v-for с ref в vue 2 возникает множество проблем. Следуйте этой проблеме:

v-for, ссылки и доступ к ссылкам. по индексу массива после Array.unshift

Как сказал Эван Ю, эта проблема решена в vue 3:

Обратите внимание, что ссылки v-for не гарантируют тот же порядок, что и исходный массив.

В следующем выпуске вы сможете определить, как регистрировать ссылки самостоятельно, передав функцию в: ref.

Я пытаюсь исправить ваш код, но не могу найти способ. Возможно, вам придется работать с DOM напрямую.

Если я найду ответ, я скоро обновлю свой ответ.

1
Nima Ebrazeh 17 Сен 2021 в 19:56