Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to preview multiple files before uploading in vue.js

Tags:

vue.js

I'm trying to preview multiple images been selected before uploading in vue.js. looks like i'm doing something wrong but can't figure out what. I will appreciate some guidance please. Find below my component:

<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>
like image 900
banky Avatar asked Dec 24 '22 08:12

banky


2 Answers

This works well.

Html Section

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

In JS section

 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]);
      }
    }
  }
})

Working Demo here: https://jsfiddle.net/Diwas_Poudel/1rLgzjvk/8/

Source

like image 186
Diwas Poudel Avatar answered Jan 05 '23 01:01

Diwas Poudel


I will introduce a div into the template to hold the files you want to preview:

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

Then to handle the image preview in your onFileChange method;

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]);
}
like image 35
Flexi Avatar answered Jan 05 '23 01:01

Flexi