File Input Component を活用しよう!
みなさん、こんにちは。どんぶラッコです。
本日は、Nuxt.js 上でファイルを受け取るにはどうすれば良いかについてご紹介します!
今回もCSSフレームワークとしてVuetifyを使って実装を進めていきます。
Vuetifyではファイル入力の際に利用できるコンポーネントとして、File Input Componentが用意されています。
これを使って実装していきましょう!
サンプルコード
<template>
<v-row>
<v-col>
<v-file-input
label="テキストファイルを選択"
@change="getFileContent"
/>
{{ content }}
</v-col>
</v-row>
</template>
<script>
export default {
data () {
return {
content: ''
}
},
methods: {
async getFileContent (file) {
try {
const content = await this.readFileAsync(file)
this.content = content
} catch (e) {
console.log(e)
}
},
readFileAsync (file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => {
resolve(reader.result)
}
reader.onerror = reject
reader.readAsText(file)
})
}
}
}
</script>
するとこんな画面を作ることができます!
↑の例では、sample.txt というファイルを読み込み、その中身を表示させています。きちんと取得できていますね。
Template部分
ファイル入力部には先ほどもご紹介したVuetifyのv-file-input
を使用。
v-on:change
で getFileContent()
メソッドを呼び出しています。
Script部分
では、getFileContent()
では何をしているのか?みてみましょう。
async getFileContent (file) {
try {
const content = await this.readFileAsync(file)
this.content = content
} catch (e) {
console.log(e)
}
}
readFileAsync()
というメソッドでファイルを読み込み、内容を表示しています。ちなみに、引数file
には選択されたファイルを元に生成されたファイルオブジェクトが入ってきます。
そして、readFileAsync()ではこんなことをしています。async, awaitを使いたかったのでPromise型を返すようにしています。
readFileAsync (file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => {
resolve(reader.result)
}
reader.onerror = reject
reader.readAsText(file)
})
}
引数として、先ほどgetFileContentの引数として渡ってきたfileオブジェクトをそのまま渡しています。
実際のファイル読み込みには FileReader()
を利用しています。
reader.onload
は読み込みが成功した時に発火するイベント
reader.onerror
は読み込みが失敗した時に発火するイベント
です。
それぞれのイベントが発火した時にPromiseをresolve, rejectしているのです。
同期的に記述したかったのでasync, awaitを使って描きましたが、大きいファイルサイズになった時には適さないですね。
その場合はどうしたらいいのか?
それについては、また次回お話しします!