如何在Vue.js组件中渲染上传的Firebase图像

时间:2019-08-05 16:59:16

标签: javascript firebase vue.js google-cloud-firestore

我试图重新利用在Github(https://gist.github.com/LoveMeWithoutAll/02c3810c3cfc6c0f9447c3697c7431b6)上找到的Vue.js图像上传器组件,以便即使刷新后也可以将图像呈现到屏幕上。当前处于状态的组件可以成功将图像上传到Firebase存储,以及从存储中删除图像。但是,当图像存储在存储器中时,它只是暂时停留在屏幕上。刷新后消失。

为解决此问题,我尝试添加一个名为“ getData()”的函数,该函数使用“ firestorage.ref('images /'+ this.fileName).get()”检索图像,并将其推入名为“ imgs”,然后使用v-for循环将它们返回到DOM(例如imgs中的img)。到目前为止,这是我的代码:

<template>
  <div>
    <v-btn @click.native="selectFile">
        Upload a cover image
        <v-icon right aria-hidden="true">add_a_photo</v-icon>
    </v-btn>
    <input id="files" type="file" name="file" ref="uploadInput" accept="image/*" :multiple="false" @change="detectFiles($event)" />
      <v-progress-circular v-if="uploading && !uploadEnd"
        :size="100"
        :width="15"
        :rotate="360"
        :value="progressUpload"
        color="primary">
        {{ progressUpload }}%
      </v-progress-circular>

        <v-card v-for="img in imgs" :key="img.id">
          <img v-if="uploadEnd" :src="downloadURL(img.fileName)" width="25%" />
        </v-card>

      <div v-if="uploadEnd">
        <v-btn class="ma-0" dark small color="error" @click="deleteImage()">
          Delete
        </v-btn>
      </div>
  </div>
</template>

<script>
// Thanks Marcelo Forclaz(https://github.com/CristalT) https://gist.github.com/CristalT/2651023cfa2f36cddd119fd979581893
// Thanks Matteo Leoni(https://github.com/signalkuppe) https://github.com/signalkuppe/vuetify-cloudinary-upload/blob/master/src/components/v-cloudinary-upload.vue
import { firestorage } from '@/firebase/firestorage'

export default {
  data () {
    return {
      imgs: [],
      progressUpload: 0,
      fileName: '',
      uploadTask: '',
      uploading: false,
      uploadEnd: false,
      downloadURL: ''
    }
  },
  created() {
    this.getData()
  },
  methods: {
    getData() {
      let snapshot = firestorage.ref('images/' + this.fileName).get()
      let imgs = []
        snapshot.forEach((doc) => {
          let appData = doc.data()
          appData.id = doc.id
          imgs.push(appData)
        })
        this.imgs = imgs
    },
    selectFile () {
      this.$refs.uploadInput.click()
    },
    detectFiles (e) {
      let fileList = e.target.files || e.dataTransfer.files
      Array.from(Array(fileList.length).keys()).map(x => {
        this.upload(fileList[x])
      })
    },
    upload (file) {
      this.fileName = file.name
      this.uploading = true
      this.uploadTask = firestorage.ref('images/' + file.name).put(file)
      .then(() => {
        this.getData()
      })
    },
    deleteImage () {
      firestorage
        .ref('images/' + this.fileName)
        .delete()
        .then(() => {
          this.uploading = false
          this.uploadEnd = false
          this.downloadURL = ''
        })
        .catch((error) => {
          console.error(`file delete error occured: ${error}`)
        })
    }
  },
  watch: {
    uploadTask: function () {
      this.uploadTask.on('state_changed', sp => {
        this.progressUpload = Math.floor(sp.bytesTransferred / sp.totalBytes * 100)
      },
      null,
      () => {
        this.uploadTask.snapshot.ref.getDownloadURL().then(downloadURL => {
          this.uploadEnd = true
          this.downloadURL = downloadURL
          this.$emit('downloadURL', downloadURL)
        })
      })
    }
  }
}
</script>

<style>
.progress-bar {
  margin: 10px 0;
}
input[type="file"] {
  position: absolute;
  clip: rect(0,0,0,0);
}
</style>

我希望在屏幕上看到返回到各个Vuetify卡的图像,相反,我不断收到一条错误消息,指出“ firestorage.ref('images /'+ this.fileName).get()”是不是功能。我还有别的方法代替.get()吗?关于如何使用图像检索而不是以上方法的任何建议?谢谢!

0 个答案:

没有答案