LoginSignup
24
17

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-03-30

きっかけ

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が

スクリーンショット 2020-03-31 6.51.22.png

'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>
24
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
17