【问题标题】:Vuefire get Firebase Image UrlVuefire 获取 Firebase 图片网址
【发布时间】:2017-10-17 15:53:52
【问题描述】:

我将我希望显示的每个项目的图像的相对路径存储在我的 firebase 数据库中。我无法让图像出现在屏幕上,因为我需要异步获取图像。 firebase 架构目前如下:

{
  items: {
    <id#1>: {
      image_loc: ...,
    },
    <id#2>: {
      image_loc: ...,
    },
  }
}

我想在我的页面上显示这些图像中的每一个,代码如下:

<div v-for="item in items">
  <img v-bind:src="item.image_loc">
</div>

这不起作用,因为我的相对位置指向 Firebase 存储中的某个位置。从这个相对 url 中获取真实 url 的相关代码是:

firebase.storage().ref('items').child(<the_image_loc>).getDownloadURL()

返回一个带有真实 url 的承诺。这是我当前的 vue.js 代码:

var vue = new Vue({
  el: '.barba-container',
  data: {
    items: []
  },
  firebase: function() {
    return {
      items: firebase.database().ref().child('items'),
    };
  }
});

我尝试过使用计算属性,包括使用 vue-async-computed,但这些解决方案似乎不起作用,因为我无法传入参数。

基本上,我如何显示一个元素列表,其中每个元素都需要一个承诺的结果?

【问题讨论】:

    标签: firebase firebase-realtime-database vue.js firebase-storage vuefire


    【解决方案1】:

    我能够通过使用 vue.js 的 asyncComputed 库并承诺一次下载所有图像而不是尝试单独下载来解决这个问题。

    /**
     * Returns a promise that resolves when an item has all async properties set
     */
    function VotingItem(item) {
      var promise = new Promise(function(resolve, reject) {
        item.short_description = item.description.slice(0, 140).concat('...');
    
        if (item.image_loc === undefined) {
          resolve(item);
        }
        firebase.storage().ref("items").child(item.image_loc).getDownloadURL()
          .then(function(url) {
            item.image_url = url;
            resolve(item); 
          })
          .catch(function(error) {
            item.image_url = "https://placeholdit.imgix.net/~text?txtsize=33&txt=350%C3%97150&w=350&h=150";
            resolve(item);
          });   
      });  
      return promise;
    }
    
    var vue = new Vue({
      el: '.barba-container',
      data: {
        items: [],
        is_loading: false
      },
      firebase: function() {
        return {
          items: firebase.database().ref().child('items'),
        };
      },
      asyncComputed: {
        processedItems: {
          get: function() {
            var promises = this.items.map(VotingItem);
            return Promise.all(promises);
          },
          default: []
        }
      }
    });
    

    最后,我需要在我的模板中使用:v-for="item in processedItems" 来渲染附有图片网址的项目

    【讨论】:

      【解决方案2】:

      我能够在没有任何额外依赖项的情况下解决它,在解析 url 之前不会向数组添加元素:

      在我的模板中:

      <div v-for="foo in foos" :key="foo.bar">
        <img :src="foo.src" :alt="foo.anotherbar">
        ...
      </div>
      

      在我的组件中(例如在mounted() 中)

      const db = firebase.firestore()
      const storage = firebase.storage().ref()
      const _this = this
      
      db.collection('foos').get().then((querySnapshot) => {
        const foos = []
        querySnapshot.forEach((doc) => {
          foos.push(doc.data())
        })
        return Promise.all(foos.map(foo => {
          return storage.child(foo.imagePath).getDownloadURL().then(url => {
            foo.src = url
             _this.foos.push(foo)
          })
        }))
      }).then(() => {
        console.log('all loaded')    
      })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-06
        • 2017-05-25
        • 1970-01-01
        • 2018-07-21
        • 1970-01-01
        • 1970-01-01
        • 2018-01-13
        • 1970-01-01
        相关资源
        最近更新 更多