我正在构建一个可以使用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 )" />
 {{ 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);
}
}
}
答案 0 :(得分:1)
使用v-for数组时,可以传递2个参数。第一个是迭代的项目,第二个是该项目的索引。所以现在,这个:
<div v-for="(file, key) in files">
<img class="preview" v-bind:ref="'image' +parseInt( key )" />
 {{ 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
或类似的prop作为唯一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" />
 {{ 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
方法,并允许您删除该特定元素,而无需先“查找”文件的索引
修改:从file
方法中删除了cancelImage
,因为只需要索引。