2020-12-12 :

nuxt-ts day13:画像アップローダーを作ろう 3


完成しました。これで楽に画像をブログに挿入できるようになりました。

アップロード処理

ブラウザからファイルを読み込み、まずはファイルサイズのチェック。通ったら、storageに保存して、画像URLなどをfirestoreにも保存しておく。エラーハンドリングはもうちょい上手いやり方がありそう。

pages\uploader.vue
  const uplaodFile = (event: any): void => {
    info.message = ''
    const file = event.target.files[0]
    if (!file) { return }
    if (file.size >= 10000000) { return } // 10MB以上の画像は弾く
    const Ref = storageRef.child('images/' + file.name)
    Ref.put(file).then(() => {
      firebase.storage().ref('images/' + file.name).getDownloadURL().then((url) => {
        db.collection('images').add({
          name: file.name,
          image_url: url,
          size: file.size,
          time: new Date().toLocaleString('ja-JP', { timeZone: 'Asia/Tokyo' })
        })
          .then(function (docRef) {
            info.message = 'アップロードが完了しました'
            listImageFile() // アップロードした画像の情報をfirestoreから取得
            console.log('Document written with ID: ', docRef.id)
          })
          .catch(function (error) {
            console.error('Error adding document: ', error)
          })
      }).catch((error) => {
        console.log(error)
      })
    })
    setTimeout(function () { info.message = '' }, 5000) // アップロード時のメッセージを消す
  }

クリップボードにコピー

pages\uploader.vue
  <div v-for="item in info.imagelist" :key="item.key" class="py-1 text-gray-800 break-all">
    <button class="hover:bg-blue-700 text-white font-bold py-1 px-1 rounded" @click="copySomething(item)">
      <img :src="item" alt="" class="w-24">
    </button>
  </div>

このように画像それぞれをボタンにしており、画像をクリックすると以下のようなテキストがコピーされるようになっている。これをブログにそのまま貼り付けるだけでその画像が表示される。便利!

![](https://firebasestorage.googleapis.com/v0/b/hukurouo.appspot.com/o/images%2Fh_christmas.jpg?alt=media&token=f1270fe6-3628-461e-8c29-5ae74c6e8ebe)

このクリップボードにコピーするという処理が結構曲者だった。nuxt-clipboard2というライブラリを使ってみたが、compostionAPI + typescript とどうも相性が悪いようで上手くいかず。しかし色々と調べていると、ライブラリを使わなくても以下の記述で簡単に実装ができた。

pages\uploader.vue
  const copySomething = (text: string): void => {
    navigator.clipboard.writeText('![](' + (text) + ')').catch((e) => {
      console.error(e)
    })
  }