Vue.js:从 Firebase 存储中检索数据后如何异步加载模板?

Posted

技术标签:

【中文标题】Vue.js:从 Firebase 存储中检索数据后如何异步加载模板?【英文标题】:Vue.js: How to load a template asynchronously after I retrive data from firebase storage? 【发布时间】:2020-05-08 13:05:10 【问题描述】:

所以,我正在尝试从我的 firebase 存储中检索一些 pdf 的链接。当我获得链接时,我想将它们绑定到某些列表。问题是在获取链接之前加载了模板,因此列表的 href 属性仍然为空。我也在使用 Vuetify。

这是我的模板

<template>
  <v-layout row wrap v-if="count > 0">
    <v-flex v-for="n in count" :key="n">
      <v-card:href="link[n-1]" target="_blank">
        <v-icon>mdi-file-pdf</v-icon>
        <span>Module n</span>
      </v-card>
    </v-flex>
  </v-layout>

这是我的脚本

<script>
import firebaseApp from "@/firebase/init.js";
var storage = firebaseApp.storage();
var storageRef = storage.ref();
export default 
  name: "Dashboard",

  data() 
    return 
      id: this.$route.params.id,
      count: null,
      link: [],
      loading: null
    ;
  ,

  methods: 
    getFile() 
      this.link = [];
      this.loading = true;
      var listRef = storageRef.child(`folder_name$this.id`);

      listRef.listAll().then(res => 
        this.count = res.items.length;
        for (let i = 1; i <= this.count; i++) 
          var starsRef = storageRef.child(`folder_name$this.id/file_name$i.pdf`);
          starsRef.getDownloadURL().then(url => 
            this.link[i - 1] = url;
          );
        
        this.loading = false;
      );
    ,
    updateId() 
      this.id = this.$route.params.id;
      this.getFile();
    
  ,

  created() 
    this.getFile();
  ,

  watch: 
    $route: "updateId"
  
;
</script>

链接数组最终将存储所有链接。但它不会绑定到 span 标签 我如何在不使用 vuex 的情况下克服这个问题? 提前致谢

【问题讨论】:

我没有看到代码有任何问题尝试查看countlink 是否真的用console.log 或Vue devtools 更新 嘿@Pierre,只有计数得到更新,我能够看到所有跨度标签。但是在渲染模板之前,`link 数组没有得到更新 【参考方案1】:

getDownloadURL() 方法是异步的,并返回一个 Promise。由于您希望对storageRef.child('folder_name$this.id') 中的所有文件并行执行此方法,因此您应该使用Promise.all() 等待所有异步操作完成,然后再更新link 数组。

以下使用forEach() 而不是for 循环应该可以解决问题(未经测试):

 listRef.listAll()
 .then(res => 
    const promises = [];
    res.items.forEach(itemRef =>     //items is an array of Reference
         promises.push(itemRef.getDownloadURL());
    );
    return Promise.all(promises);
 .then(urls => 
   this.link = urls;
 );

然后,在你的组件中你会这样做:

  <v-layout row wrap v-if="count > 0">
    <v-flex v-for="(item, index) in link">
      <v-card :href="item" target="_blank">
        <v-icon>mdi-file-pdf</v-icon>
        <span>Module index + 1</span>
      </v-card>
    </v-flex>
  </v-layout>

【讨论】:

以上是关于Vue.js:从 Firebase 存储中检索数据后如何异步加载模板?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Vue js 中尝试从 firebase 检索令牌时出现错误?

如何从 Firebase 存储中删除 Vue.js 组件图像?

Firebase:Vue.js:无法将存储与数据库连接

从firebase实时数据库IOS Swift中检索数据

Vue.js 和 Nuxt.js 中的 Firebase 存储 CORS 错误

如何从 Vue Web 应用程序中的 Firebase 存储下载文件?