如何在Vue.js中上传多个文件之前预览这些文件?

6

我正在尝试在vue.js中上传多张图片之前预览这些图片。看起来我做错了什么,但是无法弄清楚问题所在。请帮我指导一下。以下是我的组件:

<template>
  <div class="form-group">
    <textarea name="body" class="form-control" v-model="body" rows="4" placeholder="What's on your mind"></textarea>
  </div>
  <div class="form-group">
    <div v-if="attach">
        <img :src="selectedFile" style="width:70px; height:60px" />
        <button type="button" class="btn btn-danger" @click.prevent="cancelImage">Cancel</button>
    </div>
    <div v-else>
        <input type="file" @change="onFileChange" class="btn btn-default" multiple>
    </div>
  </div>
  <div class="form-group">
    <button type="button" class="btn btn-primary" @click.prevent="sendPost">Post</button>
  </div>
</template>

<script>
    export default {
      data(){
        return {
          body: '',
          images: [],
          attach: false,
          selectedFile: ''
        }
      },
      methods: {
        onFileChange(e){
          var files = e.target.files;
          if(files){
            var files_count = files.length;
            for (let i=0; i<files_count; i++){
              var reader = new FileReader();
              reader.onload = function(e){
                this.selectedFile = e.target.result;
              }
              reader.readAsDataURL(files[i]);
            }
          }
        }
      }
    }
</script>

请问您能否清楚地解释一下问题是什么?您的控制台中是否出现了任何特定的错误信息? - Phil
在您的FileReader onload处理程序中,this是FileReader。另外,我不知道vue.js什么时候会尝试使用这个值?而且您的逻辑无论如何都不适用于多个文件。最终,您甚至不需要FR,可以使用同步URL.createObkectURL创建blobURI。 - Kaiido
onFileChange(e) { this.selectedFile = URL.createObjectURL(e.target.files[0]); }再次强调,您的逻辑不允许多个文件,因此可以删除循环。 - Kaiido
@Kaiido。我删除了循环并使用了{ this.selectedFile = URL.createObjectURL(e.target.files[0]); },但是控制台上出现了这个错误。Uncaught TypeError: Cannot read property '0' of undefined at FileReader.reader.onload (app.js:46112) - banky
既然我们已经删除了FileReader,那么在onload处理程序中如何出现错误呢? - Kaiido
显示剩余2条评论
3个回答

8

这个很有效。

HTML 部分

<script src="https://unpkg.com/vue"></script>

<div id="app">
   <input
          type="file"
          multiple
          accept="image/jpeg"
          @change="onFileChange"
          />

  <div v-for="(image, key) in images" :key="key">
    <div>
      <img class="preview" :ref="'image'" />
      {{ image.name }}
    </div>
  </div>
</div>

在JS部分

 new Vue({
  el: '#app',
  data: {
    images: [],
  },
   methods: {
    onFileChange(e) {
      let vm = this;
      var selectedFiles = e.target.files;
      for (let i = 0; i < selectedFiles.length; i++) {
        console.log(selectedFiles[i]);
        this.images.push(selectedFiles[i]);
      }

      for (let i = 0; i < this.images.length; i++) {
        let reader = new FileReader();
       reader.onload = (e) => {
          this.$refs.image[i].src = reader.result;

          console.log(this.$refs.image[i].src);
        };

        reader.readAsDataURL(this.images[i]);
      }
    }
  }
})

演示地址: https://jsfiddle.net/Diwas_Poudel/1rLgzjvk/8/

来源


7
我会在模板中引入一个div来存储你想预览的文件:
<div v-for="(image, key) in images">
    <div>
        <img class="preview" v-bind:ref="'image' +parseInt( key )" /> 
        {{ image.name }}
    </div>
</div>

然后,在您的onFileChange方法中处理图像预览;
var selectedFiles = e.target.files;
for (var i=0; i < selectedFiles.length; i++){
    this.images.push(selectedFiles[i]);
}

for (var i=0; i<this.images.length; i++){
    let reader = new FileReader(); //instantiate a new file reader
    reader.addEventListener('load', function(){
      this.$refs['image' + parseInt( i )][0].src = reader.result;
    }.bind(this), false);  //add event listener

    reader.readAsDataURL(this.images[i]);
}

2
@flexi的回答是非常正确的。只需将var替换为let就不会出现任何错误。"最初的回答"
var selectedFiles = e.target.files;
for (let i=0; i < selectedFiles.length; i++){
    this.images.push(selectedFiles[i]);
}

for (let i=0; i<this.images.length; i++){
    let reader = new FileReader(); //instantiate a new file reader
    reader.addEventListener('load', function(){
      this.$refs['image' + parseInt( i )][0].src = reader.result;
    }.bind(this), false);  //add event listener

    reader.readAsDataURL(this.images[i]);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接