【问题标题】:Delete image from preview in vuejs从 vuejs 中的预览中删除图像
【发布时间】:2021-09-17 17:46:47
【问题描述】:

所以我在 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 = ""
}

但问题在于:例如,我上传了三张图片,然后单击以删除第二张图片(在中间),但它删除了中间的图片(我点击了)和最后一张图片(我没有'不要点击删除)。因此,基本上只需单击一下即可删除两个图像。

有什么建议可以解决这个问题吗?

【问题讨论】:

标签: javascript html vue.js


【解决方案1】:

切片数组后隐藏第三个。

切片前的索引 0 1 2

切片后的索引 0 1

数组中的 2 变为 1。试着评论最后一行

edit:并且图像仍然绑定到索引。所以我只是重写了代码:

<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>

【讨论】:

  • 我已经尝试过了,但它引入了另一个问题。例如:我再次上传三张图片,然后单击以删除第二张图片(中间一张),当我单击按钮时,它会从this.productImages 中删除右边的一张(中间图片),但从预览中它会删除最后一张,我仍然可以看到我从this.productImages 删除的图片,所以基本上我看到的是第一张和第二张上传的图片,但应该是第一张和最后一张图片。希望我能理解地解释它。
  • 尝试console.log(selectedFiles.length)console.log(this.productImages.length),然后在删除第二个之后再添加 3 个。也许记忆中发生了一些奇怪的事情。
  • 似乎一切正常,老实说,我现在不知道如何解决这个问题以及如何解决,尝试了一切。
  • @Edga 我只是重现了您的问题并找到了解决方案,但我不太喜欢它。但是在编程中,“如果它有效,请不要修复它”。您需要为循环中的每个图像重新应用 src。
  • 是的,它成功了,非常感谢您抽出宝贵的时间。对我来说,现在最重要的是它会按照我需要的方式工作:)
【解决方案2】:

实际使用v-forref在vue 2中有很多问题,请关注这个问题:

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

正如 Evan You 所说,这个问题在 vue 3 中解决了:

请注意,v-for refs 不保证与源数组的顺序相同。

在下一个版本中,您可以通过以下方式自行决定如何注册 refs 将函数传递给 :ref.

我尝试修复您的代码,但找不到方法。也许您必须直接使用 DOM。

如果我找到答案,我会尽快更新我的答案。

【讨论】:

    【解决方案3】:

    尝试调用方法渲染图片:

    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>

    【讨论】:

      猜你喜欢
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      • 2012-11-29
      • 1970-01-01
      • 2018-03-29
      • 2018-06-12
      • 2016-10-23
      • 2020-05-06
      相关资源
      最近更新 更多