Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

216
Visualizações
Delete image from preview in vuejs

So I am doing multiple images upload, preview and delete in vue js. Here it is what I have:

<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 = ""
}

But here is the problem with this: for example I upload three images and I click to remove second image (in the middle), but it removes image in the middle (which I clicked) and the last image (which I didn't click to remove). So basically with one click it removes two images.

Any suggestions how to fix this?

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Actually using v-for with ref has a lot of issues in vue 2. Please follow this issue:

v-for, refs and access to refs. by array index after Array.unshift

As Evan You said, this problem solved in vue 3:

Note that v-for refs do not guarantee the same order as your source Array.

In the next release you can determine how to register refs yourself by passing a function to :ref.

I try to fix your code but I can't find a way. Maybe you have to work with DOM directly.

If I find an answer, I will update my answer soon.

about 4 years ago · Juan Pablo Isaza Relatório

0

You are hiding the 3rd one after slicing the array.

index before slice 0 1 2

index after slice 0 1

The 2 become 1 in the array. Just try to comment the last line

edit: And image is still binding to is index. So I just rewrite the code :

<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>
about 4 years ago · Juan Pablo Isaza Relatório

0

Try to call method to render images:

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>

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda