[Rails×Vue.js]複数枚画像のプレビュー表示を実装していきます

今回はなんとなく気になっていたvue.jsでの画像プレビュー表示です。

vue.jsはudemyでなんとなく勉強しただけで、特にアプトプットをしていませんでした。

いい機会なのでアウトプットしていきます。

versions
  • ruby 2.6.5
  • rails 6.1.1

railsにvue.jsを導入しよう

まずはwebpacker経由でvue.jsをインストールしていきましょう。

~任意のrailsディレクトリ~$ rails webpacker:install:vue

たったのこれだけでvue.jsが使用できるようになります!

Vue.jsを実装しよう

コードを先に貼っておきます。

<template>
  <div class="click-upload">
    <img v-for="image in images" :src="image">
    <p>
      クリックしてファイルをアップロード
    </p>
    <input type="file" @change="onImageChange" name="item[images][]" multiple="multiple">
  </div>
</template>

<script>
export default {
  data() {
    return {
      images: []
    }
  },
  methods: {
    getBase64(file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => resolve(reader.result);
        reader.onerror = error => reject(error);
      })
    },
    onImageChange(e) {
      const images = e.target.files;
      for (var i=0; i < images.length; i ++) {
      this.getBase64(images[i])
        .then(image => this.images.push(image))
        .catch(error => this.setError(error, '画像のアップロードに失敗しました。'))
      }
    }
  }
}

切り出した関数ごとに解説していきます。

 getBase64(file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => resolve(reader.result);
        reader.onerror = error => reject(error);
      })
    }

ここはjavascriptでもお馴染みのFileReaderクラスの関数です。

Promiseを利用して例外処理もしています。

onImageChange(e) {
      const images = e.target.files;
      for (var i=0; i < images.length; i ++) {
      this.getBase64(images[i])
        .then(image => this.images.push(image))
        .catch(error => this.setError(error, '画像のアップロードに失敗しました。'))
      }
    }

 今回は複数枚投稿を想定しているので、配列にpushしています。

意外とあっさりできて感動しています!

参考

vue.js で複数ファイルアップロード、プレビュー表示