Search code examples
javascripthtmlvue.jsbindv-model

V-model directives don't support input type="file"


I am trying to update the user profile data in my database, but I am stuck at the user profile image. I can't use the v-model for binding, and with v-on:change it doesn't work. This is my code so far, it is working properly, the only issue being the binding.

<template>
-----
          <div v-if="!image">
            <h2>Select an image</h2>
            <input type="file" @change="onFileChange" /> ---->here I would like to use the v-model but can't use it on input type="file"
          </div>
          <div v-else>
            <img :src="image" />
            <button @click="removeImage">Remove image</button>
          </div>
          <input
            type="text"
            placeholder="Userame"
            v-model="user.username"
            required
          />
          <button
            type="button"
            class="btn btn-outline-warning waves-effect"
            aria-label="Left Align"
            @click.prevent="updateProfile(user)"
          >
            Update profile
          </button>
       ---
</template>

<script>
export default {
  data: function () {
    return {
      user: {},
       image: ''
    };
  },

  methods: {
    onFileChange(e) {
      var files = e.target.files || e.dataTransfer.files;
      if (!files.length)
        return;
      this.createImage(files[0]);
    },
    createImage(file) {
      var image = new Image();
      var reader = new FileReader();
      var vm = this;

      reader.onload = (e) => {
        vm.image = e.target.result;
      };
      reader.readAsDataURL(file);
      console.log(file.name);
    },
    removeImage: function (e) {
      this.image = '';
  },
    updateProfile() {
      store
        .dispatch("updateProfile", {
          username: this.user.username,
          email: this.user.email,
          profileImage: this.file ------>I need it for the binding here

</script>

Solution

  • You forgot to bind the file to this.file. Update your onFileChange method to this 👇🏻, it will work.

    Note: v-model only works with input which use value binding, where input type file doesn't use input value, it makes no sense to use input type file with v-model

    onFileChange(e) {
          var files = e.target.files || e.dataTransfer.files;
          if (!files.length) return;
          this.file = files[0]
          this.createImage(this.file);
        },