したたかに。したたかに。

webプログラマーです。2020年2月からフリーランスになります。フリスビーを投げるのが趣味です。

【Vue + Vuetify】選択した画像ファイルをブラウザにプレビュー表示させる

やりたいこと

入力フォームで画像を選択し、それをブラウザに表示させたい。
使用するフレームワークはVue + Vuetify。

Image from Gyazo

やること

やることは以下の3つ

  • inputタグとimgタグを配置する
  • inputタグにファイルを読み込む関数を紐付ける
  • ファイルを読み込む処理を実装する

実装

inputタグとimgタグを配置する

vuetifyで提供されている入力フォーム <v-file-input />タグと、 取り込んだ画像を表示させるためのimgタグを配置します。

<template>
  <div>
    <div>
      <!-- 読み込んだ画像をここに表示させる。'iconImage'に画像のURLを代入して表示させる。 -->
      <img :src='iconImage' />
    </div>
    <!-- inputタグの配置 -->
    <v-file-input></v-file-input>
  </div>
</template>

<script>
// デフォルトで表示させる画像をimportする。フォルダのパスは任意で変更する。
import iconImage from '~/components/images/user-alt-solid.svg'

export default {
  data () {
    return {
      // 画像のURLを保持するための変数を定義
      iconImage
    }
  }
}
</script>

inputタグにファイルを読み込む関数を紐付ける

次に、changeイベントとファイルを取り込む関数を紐付けます。

ファイルを選択し、それを表示させるまでの流れはこのような形。


v-on:changeでgetFileContent()を呼び出す。

getFileContent()readFileAsync() を呼び出す。

readFileAsync()で画像を読み込み表示する。


画像ファイルの読み込みは、非同期で行う為asyncを使用して関数を定義しています。

<template>
  <div>
    <div>
      <img :src='iconImage' />
    </div>
    <!-- v-onで画像を取り込む処理を呼び出す。 -->
    <v-file-input v-on:change="getFileContent"></v-file-input>
  </div>
</template>

<script>
import iconImage from '~/components/images/user-alt-solid.svg'

export default {
  data () {
    return {
      iconImage
    }
  },
  methods: {
    // ファイルを取り込む関数をasyncを用いて定義
    async getFileContent (file) {  

      // ファイルを読み込む関数は同期的に扱うのでawaitを使用して呼び出す。
      await this.readFileAsync(file)
    },

    // ファイルを読み込む関数を定義しておく
    readFileAsync (file) {
    }
  }
}
</script>

ファイルを読み込む処理を実装する

最後に、選択された画像ファイルの情報を読み取り、imgタグのurl属性に値を代入します。

これによって、選択した画像が表示されます。

画像の読み取り関数は、成功時、失敗時で後続に実行する処理を分けたいので、Promiseオブジェクトを使用します。 (今回は読み取りが失敗した場合の処理のみを定義します。)

<template>
  <div>
    <div>
      <img :src='iconImage' />
    </div>
    <v-file-input v-on:change="getFileContent" label="Image"></v-file-input>
  </div>
</template>

<script>
import iconImage from '~/components/images/user-alt-solid.svg'

export default {
  data () {
    return {
      iconImage
    }
  },
  methods: {
    async getFileContent (file) {  

      // ".catch( ~~~ )"を付与することで"readFileAsync()"が失敗したときの振る舞いを定義する。
      // 今回は、エラーが発生したらログをコンソールに吐き出す仕様にする。
      await this.readFileAsync(file).catch(error => console.log(error))
    },

    readFileAsync (file) {

      // Promiseオブジェクトに画像を読み込む関数を定義する。
      return new Promise((resolve, reject) => {

        // FileReaderオブジェクトに画像ファイルのurlを取り出し、変数へ格納する処理を定義する。
        const reader = new FileReader()
        reader.onload = (file) => {
          this.iconImage = file.target.result
        }

        // 画像ファイルの読み込みを行う。読み込みが完了した後に、上記でreader.onloadに格納した処理が実行される。
        reader.readAsDataURL(file)
      })
    }
  }
}
</script>

以上で選択した画像ファイルがプレビュー表示出来るようになるかと思います。

まとめ

読み込んだ画像を表示させるステップを3つに分けて説明しました。

解説中に使用したPromise, async/awaitについてはこちらの記事がとても参考になりましたので、まだ非同期関数の使い所がいまいち理解できていないという方は一読することをお勧めします!

sbfl.net



以上となります、最後までご覧いただきありがとうございました!