【问题标题】:How to cancel previewed image and name of files to be uploaded with vue.js如何取消预览的图像和要使用 vue.js 上传的文件的名称
【发布时间】:2018-09-14 10:21:49
【问题描述】:

我正在构建一个可以使用 vue.js 一次上传多个图像的应用程序。在文件输入的@change 事件中(当我选择要上传的文件时),我想要一个预览和所选图像的名称,然后是一个取消单个文件的按钮。一切正常。但是,当我尝试使用按钮取消任何图像时,只有名称被删除,图像仍然存在。有人可以指导我纠正我做错了什么。问题似乎与我的cancelImage 方法有关。 我的模板:

<div class="form-group">
  <textarea name="body" class="form-control" v-model="body"></textarea>
</div>
<div class="form-group">
  <label class="control-label">Files
  <input type="file" ref="files" accept="image/*" multiple="multiple" @change="selectFiles">
  </label>
</div>
<div v-for="(file, key) in files">
    <img class="preview" v-bind:ref="'image' +parseInt( key )" /> 
    &nbsp{{ file.name }}
    <button type="button" class="btn btn-danger" @click.prevent="cancelImage(file, key)"> X </button>
</div>
<div class="form-group">
    <button @click.prevent="addFiles" class="btn btn-default">Add Files</button>
</div>
<div class="form-group">
    <button type="button" class="btn btn-primary btn-block" @click.prevent="upload">Upload</button>
</div>

然后是我的脚本:

export default {
      data(){
        return {
          body: '',
          files: [],
          form: new FormData()
        }
      },
      methods: {
        uploadFiles(e){
          let selectedFiles = e.target.files;
          let vm = this;
          for (let i=0; i < selectedFiles.length; i++){
            vm.files.push(selectedFiles[i]);
          }
          this.imagePreview();
          console.log(this.files)
        },
        imagePreview(){
          let vm = this;
          for (let i=0; i<vm.files.length; i++){
            let reader = new FileReader();

            reader.addEventListener('load', function(){
              vm.$refs['image' + parseInt( i )][0].src = reader.result;
            }.bind(vm), false);
            reader.readAsDataURL(vm.files[i]);
          }
        },
        addFiles(){
          this.$refs.files.click();
        },
        cancelImage(file){
           let index = this.files.indexOf(file);
           this.files.splice(index, 1);
        }
     }
  }

【问题讨论】:

  • 尝试在使用v-for的地方添加key&lt;div v-for="(item, key) in items" :key="key"/&gt;

标签: javascript vue.js


【解决方案1】:

当使用 v-for 数组时,您可以传递 2 个参数。第一个是被迭代的项目,第二个是该项目的索引。所以现在,这个:

<div v-for="(file, key) in files">
    <img class="preview" v-bind:ref="'image' +parseInt( key )" /> 
    &nbsp{{ file.name }}
    <button type="button" class="btn btn-danger" @click.prevent="cancelImage(file, key)"> X </button>
</div>

可能没有完全按照你的想法去做。 file 是您正在迭代的项目(推送的formData),key 实际上是您的 files 数组中项目的索引。通常,v-for 中的 key 用于为每个元素添加唯一标识符,以帮助 Vue 知道哪个元素是哪个。您可以将其与:key 属性一起使用(类似于file.id 或任何适合您作为唯一ID 的道具)。所以尝试这样的事情:

HTML:

<div v-for="(file, index) in files" :key="file.name"> // This is a terrible key, but I am not sure what properties exist on your formData objects.
    <img class="preview" v-bind:ref="'image' + index" /> 
    &nbsp{{ file.name }}
    <button type="button" class="btn btn-danger" @click.prevent="cancelImage(index)"> X </button>
</div>

JS:

cancelImage(index){
  this.files.splice(index, 1);
}

由于 v-for 正在为数组中的每个元素创建一个按钮,这会将索引传递给 cancelImage 方法,并允许您删除该特定元素而无需先“找到”文件的索引。

编辑:从cancelImage 方法中删除file,因为只需要索引。

【讨论】:

  • 感谢您的帮助。我尝试了此解决方案,但它只会删除预览中的最后一项,而与您尝试取消的项目无关。
猜你喜欢
  • 2018-12-25
  • 2014-05-20
  • 1970-01-01
  • 1970-01-01
  • 2015-07-02
  • 2020-07-14
  • 2023-03-31
  • 2013-12-02
  • 1970-01-01
相关资源
最近更新 更多