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>
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
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]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With