Guide to showing a preview of an image prior to submitting a form using vue.js

I created a Vue form but I'm having trouble making the image preview function work when users try to submit an image to the form.

After refreshing the page, I can see the image, but when uploading it, the preview link is broken. There is an option to remove an image, which works fine, but my goal now is to display an image preview.

                   <div class="image-block">
                            <div @click="selectImage('initial-image')">
                                <img class="img-icon"
                                     v-if="imageName === null">
                                <div :class="{'error' : errors.length > 0}" class="text-center"
                                     v-if="imageName === null">
                                    Select an image to upload
                                </div>
                            </div>
                            <div class="image-preview" v-if="imageName !== null">
                                <div class="remove-image" @click="removeImage"><i
                                    class="fa fa-remove"></i>
                                </div>
                                <img v-bind:src="'/images/json-ld/images/' + imageName" class="growth-image"
                                     @click="selectImage('initial-image')">
                            </div>
                        </div>
                        <validation-provider name="image" v-slot="{ validate, errors }">
                            <input type="file" @change="validate" name="image" accept="image/*"
                                   class="hidden"
                                   v-on:change="showFilePreview">
                            <span class="validation-error form-span">{{ errors[0] }}</span>
                        </validation-provider>

Methods:

 removeImage() {
            this.imageName = null;
        },
        selectImage(id) {
            document.getElementById(id).click();
        },
        showFilePreview(e) {
            let files = e.target.files || e.dataTransfer.files;
            if (!files.length) return;
            this.createImage(files[0]);
        },
        createImage(file) {
            let reader = new FileReader();
            let vm = this;

            reader.onload = (e) => {
                vm.image = e.target.result;
            };
            reader.readAsDataURL(file);
        },

Any suggestions on how to make this functionality work as intended?

Answer №1

Here is a suggestion for optimization:

<img v-bind:src="'/images/json-ld/images/' + imageName" .. />

You can simplify it to:

<img v-bind:src="image" .. />
// You can also use the bind shortcut
<img :src="image" .. />

By making this change, the preview should work correctly.

Example #1

new Vue({
  el: '#app',
  data() {
    return {
      image: null,
    }
  },
  methods: {
    showFilePreview(e) {
      let files = e.target.files || e.dataTransfer.files;
      if (!files.length) return;
      this.createImage(files[0]);
    },
    createImage(file) {
      let reader = new FileReader();
      let vm = this;
      reader.onload = (e) => {
        vm.image = e.target.result;
      };
      reader.readAsDataURL(file);
    }
  }
})
#app { padding: 10px; }
#preview img { max-width: 100%; max-height: 150px; margin-top:10px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
  <input type="file" @change="showFilePreview" />
  <div id="preview">
    <img v-if="image" :src="image" />
  </div>
</div>


Another way to optimize the code is by using URL.createObjectURL() to simplify the process:

Example #2

new Vue({
  el: '#app',
  data() {
    return {
      image: null,
    }
  },
  methods: {
    showFilePreview(e) {
      let files = e.target.files || e.dataTransfer.files;
      if (!files.length) return;
      this.image = URL.createObjectURL(files[0]);
    }
  }
})
#app { padding: 10px; }
#preview img { max-width: 100%; max-height: 150px; margin-top:10px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
  <input type="file" @change="showFilePreview" />
  <div id="preview">
    <img v-if="image" :src="image" />
  </div>
</div>

Answer №2

After successfully storing the base64 information in the vm.image variable, you can now easily insert it into the src attribute like so:

<img :src="image"/>

A more efficient way to retrieve the data is by implementing the following code snippet:

const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
     this.image = reader.result;
};

Answer №3

Thank you for taking the time to provide your insights.

Fortunately, I was able to resolve the issue by taking a different approach.

I realized that I needed to include the complete path to the image during the mounting process.

    mount() {
        axios.get('/app/json-ld/store-info')
        .then(res => {
        let data = res.data;

        this.imageName = data.store.image ? '/images/json-ld/images/' + 
    }

Then, I made sure to correctly define the src attribute as follows:

 <img v-bind:src="imageName" @click="selectImage('initial-image')">

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular 2: Store all form inputs within a JSON object upon submission

I am working on a form that has multiple fields and I need to retrieve the data once it is submitted. This is the code in component.html : <div class="ui raised segment"> <h2 class="ui header">Demo Form: Sku</h2> <form #f="ngFor ...

Issues with non-functional plugins that utilize AJAX functionality

I am encountering an issue with my code that includes an ajax script for deleting a record, along with an animation during the deletion process. However, when I try to integrate the ajax script with plugins for confirmation, it seems to not be working prop ...

Retrieve the overall number of Formik errors for a specific field array

In the given Yup validation setup below, there is a nested Formik FieldArray: parentLevel: Yup.array().of( Yup.object({ childrenLevel: Yup.array().of( Yup.object({ childName: Yup.string().required('Name is required') ...

Turning off strict mode in the bundling process of React with webpack can be achieved by following

I'm facing an issue with my application. It works perfectly in all browsers except for IE, where it throws the following error: 0x800a0416 - JavaScript runtime error: Multiple definitions of a property not allowed in strict mode In my webpack.config ...

How to flip the value in v-model using VueJS

Below is the code snippet that I am working with: <input v-model="comb.inactive" type="checkbox" @click="setInactive(comb.id_base_product_combination)" > I am looking to apply the opposite value of comb.inactive to the v-model. Here are m ...

Creating an array of objects sorted in alphabetical order

My task involves working with an array of objects that each have a name property: var myList = [{ name: 'Apple' }, { name: 'Nervousness', }, { name: 'Dry' }, { name: 'Assign' }, { name: 'Date' }] ...

The function _vm.$refs.menu.open is not defined

Utilizing vue-context to customize the default context menu, I encounter an error when trying to interact with it from a component. Below is my code snippet: <!-- Main --> <p @contextmenu.prevent="$refs.menu.open">test</p> <C ...

Tips for utilizing the loadDataWithBaseURL() method to load CSS and JS files directly from an SDCARD

I am facing an issue with loading files from SDCARD onto a webview. The .html, .js, .css files are stored on the SDCARD in my scenario, and the html file content is encrypted. The steps I follow to load the html file are: Read file content Decrypt all co ...

Is it possible for a Vue.js build to encounter errors due to unregistered components?

Exploring a component template... <template> <Unknown></Unknown> </template> In the context of this template, Unknown could be either a globally registered component or not. Upon encountering this scenario at runtime, an informa ...

Diverse behaviors exhibited by an array of promises

I've developed a function that generates an array of promises: async addDefect(payload) { this.newDefect.setNote(payload.note); this.newDefect.setPriority(payload.priority); const name = await this.storage.get(StorageKeys.NAME); ...

An easy way to activate a toggle function when the page loads in React

I want to create a nice slide-in effect for my sidebar when the user loads the page. My goal is to toggle the state of the Sidebar component from open: false to open: true on load in order to achieve this effect. Unfortunately, it seems that the way I&apo ...

The requested :id route could not be found using the findById() method in

Having trouble retrieving data using Insomnia from a specific ID in my collection. Below is the sample request URL. http://localhost:5000/todos/5dd295a49d5d7a0b7a399bbe However, when I access http://localhost:5000/todos/ without the ID, I can see all the ...

Changing global variables within a POST request

I am currently developing a quiz application for the Noops Challenge on Github, utilizing the Fizzbot API available at Noops Challenge. To keep track of the current question and the next question URLs, I have defined global variables to store and assemble ...

The issue of JavaScript Memory Leakage when utilizing FileReader and Promise

-Modify I have raised a bug report to address this issue I am attempting to upload a directory to my server containing large files, including CT scan images. While the process is functioning correctly, I am encountering memory problems. document.getElem ...

Choose the text that appears in the input or textbox field when tapping or clicking on it

Desperately Seeking a Clickable Textbox The Quest: In search of a cross-browser textbox/input field that can select its content on click or tap. An elusive challenge haunting developers for years. The Dilemma: Using a touch device triggers the tap e ...

When integrating string variables into JavaScript regular expressions in Qualtrics, they seem to mysteriously vanish

I have been working on a project to analyze survey responses in Qualtrics by counting the number of matches to specific regular expressions. For example, whenever phrases like "I think...", "In my opinion," are used, the count increases by one. Below is t ...

Orbit around a moving object in Three.js

I am working with a camera that needs to rotate around a specific target position within the scene. Despite attempts to implement a pivot concept, as suggested in this discussion: https://github.com/mrdoob/three.js/issues/1830, I have come up with my own s ...

Loop through the JSON data and display any empty strings

I encountered an issue while trying to convert an object string from a list of arrays using the JSON.parse method. Despite successfully converting the object string to an object, it appears empty when used within ng-repeat. Jade .item.col-md-4(ng-repeat= ...

Sending information to a single component among several

I'm developing a custom DownloadButton component in VueJS that features an animation when clicked and stops animating once the download is complete. The DownloadButton will be utilized within a table where it's replicated multiple times. I intend ...

What is the best way to convert items from a foreach loop into a JSON string using the json_encode() function in PHP?

I want to populate a string with all the emails fetched from the database, in order to use JavaScript for checking if the email entered by a user in a form field is already registered. I'm attempting to utilize the json_encode() function. $connec ...