DEV Community

Alan Schio
Alan Schio

Posted on • Edited on

9

Vue and Input File - Clear File or Select same file

Have you ever had the case where ou have a file selector component, you clear the file model but then you can't select the same file again?

File selection

Codepen: https://codepen.io/schirrel/pen/YzRGrvq

Well its kinda hard and curious to explain.
First of all to the TL/DR:
You need to use Vue's $refs and set the input to null.

Now if you want to understand why, let's pass thru some important stuff:

First: Vue doesn't work with v-model and file input, even has a discussion about it on the offical Vue's repo: Discussion.

Now lets undestand why doesnt work, two main things:

  1. input with type="file" only triggers change event, while v-model listen to input event.
  2. v-model needs to set the value html attribute, if you ever try to do :value="myFileModel" this error will show up:

Error in nextTick: "InvalidStateError: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.

So with this comes a question: how to a clear a file, and most important, how make it possible to select again?

Lets paint a simple use case: You have your own file wrapper the uses a file input (obviously) but you save the file on the data. Example:

<template>
 <label for="inputFile">
      Click here to select you file
      <input type="file" name="inputFile" id="inputFile" @change="selectFile" />
    </label>
    <span v-if="file">
      File Selected {{ file.name }}
      <button @click="clearFile">remove</button>
    </span>
</template>
<script>
export default {
  data() {
    return {
      file: null
    };
  },
  methods: {
    selectFile(event) {
      this.file = event.target.files[0];
    },
    clearFile() {
      this.file = null;
    }
  }
};
</script>
Enter fullscreen mode Exit fullscreen mode

Even if clearFile is setting file as null, when selecting the file again the @change wont be triggered again. Thats why because the html value attribute still the same, the file prop on data doesn't affect it. Take a look at the codepen example.

Once we have seen that :value don't work with files, the proper way to do this is acessing the HTML <input type="file" /> and reset this value programmatically.

By adding a ref="fileInput" to the <input> and inside the clearFile method add:

this.$refs.fileInput.value = null
Enter fullscreen mode Exit fullscreen mode

Now it works:

Vue select same file

The codepen final solution: https://codepen.io/schirrel/pen/XWyjeOw

Note: this is common behavior across frameworks;

Do your career a big favor. Join DEV. (The website you're on right now)

It takes one minute, it's free, and is worth it for your career.

Get started

Community matters

Top comments (1)

Collapse
 
gabrielaschlemper profile image
Gabriela Schlemper

thanks for that!

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay