File input on change in vue.js

Another solution:

<input type="file" @change="previewFiles" multiple>

methods: {
   previewFiles(event) {
      console.log(event.target.files);
   }
}

Try this.

<input type="file" id="file" ref="myFiles" class="custom-file-input" 
  @change="previewFiles" multiple>

and in your component options:

data() {
  return {
    files: [],
  }
},
methods: {
  previewFiles() {
    this.files = this.$refs.myFiles.files
  }
}

<form ref="form">
   <input type="file" @change="previewFiles" multiple tabindex="-1">
</form>

methods: {
   previewFiles(event) {

      // process your files, read as DataUrl or upload...
      console.log(event.target.files);

      // if you need to re-use field or drop the same files multiple times
      this.$refs.form.reset() 

   }
}

On Safari, you might face an issue when @input/change event won't fire.

tabindex="-1" - it's a magic trick to make it works on Safari (13.0.2)


For all the TS-Users out there:

<template>
<input ref="upload"
       type="file"
       name="file-upload"
       multiple=""
       accept="image/jpeg, image/png"
       @change="onUploadFiles">
</template>
import { Component, Prop, Vue } from 'vue-property-decorator';

@Component({ components: {} })
export default class MediaEdit extends Vue {

private onUploadFiles(event: InputEvent): void {
    const files: ReadonlyArray<File> = [...(this.upload.files ? this.upload.files : [])];

        files.forEach((file) => {
            console.log(`File: ${file.name}`);
        });
    }

    /** Upload element */
    private get upload(): HTMLInputElement {
        return this.$refs.upload as HTMLInputElement;
    }
}