Vue/Vuex/Nuxtのformでinput type='file'を指定するとv-modelが使えない


きっかけ

Nuxt.jsとRails APIを使用してアプリを作っています。
画像アップロード機能をformで作成中、v-modelでひっかかってしまったので
その対処法を載せたいと思います。

問題

formで画像をアップロードする場合、HTMLタグのinputを使うと
typeとしてはfileを選ぶことになると思います。
そしてそこで取得したデータをdata()内のObjectに格納しようと思い、
v-modelを指定しました。

<!-- ... は省略を示す -->

<template>
...
  <input type="file" v-model="submittedArticle.image" style="display: none;" />
...
</template>

<script>
...
  data() {
    return {
      submittedArticle: {
        title: "",
        description: "",
        image: null
      },
      ...
    }
  }
...
</script>

するとVSCodeからnoticeが

'v-model' directives don't support 'file' input type.

v-modelはtype="file"をサポートしていない、とのことです。

対処法

@changeを使用して対処しました。
画像をアップロードするとこのtype="file"のinputに変化が生じるので、それを見逃さないようinputに@changeをつけて監視します。
そして@changeに画像データを取得するメソッド(下記ではonImageUploaded)を結びつけることで、画像アップロード時に画像データを取得できるようにします。
あとは画像データを作成・保存するメソッドも作って、それを画像取得後に呼び出します。そこでできたObjectをdata()に格納します。

<!-- ... は省略を示す -->

<template>
...
  <input type="file" @change="onImageUploaded" style="display: none;" />
...
</template>

<script>
...
  data() {
    return {
      submittedArticle: {
        title: "",
        description: "",
        image: null
      },
      ...
    }
  },
  methods: {
    onImageUploaded(e) {
      // event(=e)から画像データを取得する
      const image = e.target.files[0]
      this.createImage(image)
    },
    createImage(image) {
      const reader = new FileReader()
      // imageをreaderにDataURLとしてattachする
      reader.readAsDataURL(image)
      // readAdDataURLが完了したあと実行される処理
      reader.onload = () => {
        this.submittedArticle.image = reader.result
      }
    },
    ...
  }
...
</script>