きっかけ
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>