0

I'm trying to display a preview of some images when a user selects them before he uploads them, but I'm new to vue and I can't figure out how to apply the background image url style to each div (it must be with background image), here is my UploadComponent so far:

<template>
    <div class="content">
            
            <h1>{{ title }}</h1>
            <div class="btn-container">
                <label class="button" for="images">Select Images</label>
                <input type="file" id="images" name="images[]" multiple="multiple" @change="selectFiles"/>
                
            </div>
            <br><br>
            <div class="block">
                <h3>Selected images</h3>
                

                <div v-for="image in images" v-bind:key="image" class="image-result" v-bind:style="{ backgroundImage: 'url(' + image + ')' }">

                </div>

            </div>
            <div class="btn-container">
                <button type="button" class="submit-btn" v-on:click="uploadImages">Submit Images</button>
            </div>
            <br><br>
            <div class="block">
                <h3>Uploaded images</h3>
                <div class="files-preview">
                    
                    
                </div>
            </div>
    </div>
  
</template>

<script>
import axios from 'axios';

export default {
  name: 'UploadComponent',
  data: () => ({
      title: 'Select your images first and then, submit them.',
      images: []
  }),
  methods:{
      selectFiles(event){
        var selectedFiles = event.target.files;
        var i = 0;

        for (i = 0; i < selectedFiles.length; i++){
            this.images.push(selectedFiles[i]);
        }

        for (i = 0; i < this.images.length; i++){
            let reader = new FileReader(); //instantiate a new file reader
            reader.addEventListener('load', function(){
                
                console.log(this);
            }.bind(this), false);  //add event listener

            reader.readAsDataURL(this.images[i]);
        }
      },
      uploadImages(){
        const data = new FormData();
        data.append('photos', this.images);

        axios.post('url')
                .then(res => {
                    console.log(res);
                });
      }
  }
}
</script>

The divs are being created but I'm missing the part where I assign the background image, how can I solve this?

1 Answer 1

1

You can't just put a File directly as the parameter for background-image. You started using FileReader but didn't do anything with the result.

Here's what I would do below, I converted your images array into a list of objects that have a file property and a preview property, just to keep the file and preview linked together.

Vue.config.productionTip = false;
Vue.config.devtools = false;

new Vue({
  el: "#app",
  data: () => {
    return {
      title: 'Select your images first and then, submit them.',
      images: []
    }
  },
  methods: {
    selectFiles(event) {
      var selectedFiles = event.target.files;

      for (var i = 0; i < selectedFiles.length; i++) {

        let img = {
          file: selectedFiles[i],
          preview: null
        };
        let reader = new FileReader();
        reader.addEventListener('load', () => {

          img.preview = reader.result;
          this.images.push(img);
        });

        reader.readAsDataURL(selectedFiles[i]);
      }
    },
    uploadImages() {

      const data = new FormData();
      data.append('photos', this.images.map(image => image.file));

      axios.post('url')
        .then(res => {
          console.log(res);
        });
    }
  }
});
.image-result {
  width: 100px;
  height: 100px;
  background-size: contain;
  background-repeat: no-repeat;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" class="content">

  <h1>{{ title }}</h1>
  <div class="btn-container">
    <label class="button" for="images">Select Images</label>
    <input type="file" id="images" name="images[]" multiple="multiple" @change="selectFiles" />

  </div>
  <br><br>
  <div class="block">
    <h3>Selected images</h3>
    <div id="target-photos">

    </div>

    <div v-for="image in images" class="image-result" v-bind:style="{ backgroundImage: 'url(' + image.preview + ')' }">

    </div>

  </div>
  <div class="btn-container">
    <button type="button" class="submit-btn" v-on:click="uploadImages">Submit Images</button>
  </div>
  <br><br>
  <div class="block">
    <h3>Uploaded images</h3>
    <div class="files-preview">


    </div>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.