You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue中如何让Firebase Storage列表加载完成后再关闭loading?

解决Firebase Storage加载完成前保持loading状态的问题

问题描述

在Vue.js视图中调用Firebase Storage组合式函数时,mixed数组初始仅显示引用,只有触发DOM更新操作后才会刷新数据。需要实现让loading状态保持为true,直到所有文件夹和文件的信息都准备完毕并推入mixed数组中。

原代码

import { ref } from "vue";
import { projectStorage } from "../firebase/config";

//all the files at the root in one array
const mixed = ref([]);
const loading = ref(true);

//function to list all the contents of a folder
const getClientFiles = async (folder) => {
  const listRef = projectStorage.ref(folder);

  listRef
    .list()
    .then((res) => {
      res.prefixes.forEach((folderRef) => {
        // All the prefixes under listRef.
        mixed.value.push({
          name: folderRef.name,
          type: "Folder",
          size: "--",
          lastUpdated: "--",
          url: "--",
        });
      });
      if (res.items.length > 0) {
        res.items.forEach((itemRef) => {
          let one = {
            name: itemRef.name,
            type: "Folder",
            size: "--",
            lastUpdated: "--",
            url: "--",
          };

          // All the items under listRef.
          itemRef.getDownloadURL().then((url) => {
            // console.log ("download url: " + url)
            one.url = url;
          });

          itemRef.getMetadata().then((metadata) => {
            // Metadata now contains the metadata for each itemRef
            (one.type = metadata.contentType),
              (one.size = metadata.size),
              (one.lastUpdated = metadata.timeCreated);
          });
          mixed.value.push(one);
        });
        console.log(mixed.value)
        loading.value = false
      }
    })
    .catch((error) => {
      // Uh-oh, an error occurred!
      console.log(error);
    }).finally(() => {
if (mixed.value.length > 0){
    loading.value = false
}
    })
}

export { getClientFiles, loading, Files, Items, mixed, meta, links };

解决方案代码

import { ref } from "vue";
import { projectStorage } from "../firebase/config";

const mixed = ref([]);
const loading = ref(true);

const getClientFiles = async (folder) => {
  loading.value = true; // 每次调用时重置loading状态
  mixed.value = []; // 清空之前的数据,避免重复累加
  const listRef = projectStorage.ref(folder);

  try {
    const res = await listRef.list();
    
    // 处理文件夹,同步操作直接push
    res.prefixes.forEach((folderRef) => {
      mixed.value.push({
        name: folderRef.name,
        type: "Folder",
        size: "--",
        lastUpdated: "--",
        url: "--",
      });
    });

    // 处理文件,等待所有异步操作完成后再push
    if (res.items.length > 0) {
      const filePromises = res.items.map(async (itemRef) => {
        // 并行获取下载链接和元数据
        const [url, metadata] = await Promise.all([
          itemRef.getDownloadURL(),
          itemRef.getMetadata()
        ]);

        return {
          name: itemRef.name,
          type: metadata.contentType,
          size: metadata.size,
          lastUpdated: metadata.timeCreated,
          url: url,
        };
      });

      // 等待所有文件的异步处理完成,把结果合并到mixed数组
      const fileItems = await Promise.all(filePromises);
      mixed.value.push(...fileItems);
    }
  } catch (error) {
    console.log(error);
  } finally {
    loading.value = false; // 无论成功失败,最终都关闭loading
  }
};

export { getClientFiles, loading, mixed };
// 注意:原导出的Files、Items、meta、links在代码中未定义,建议检查后再导出

关键修改点说明

  • 重置状态:每次调用getClientFiles时,重置loading为true并清空mixed数组,避免重复调用时数据混乱。
  • 异步操作并行处理:用Promise.all同时获取每个文件的下载链接和元数据,提升效率,确保所有异步操作完成后再生成完整的文件对象。
  • 统一时机更新数组:文件对象的所有属性都准备好后,再一次性推入mixed数组,确保Vue能及时检测到数组变化,避免初始只显示引用的问题。
  • 正确控制loading:把loading.value = false放在finally块中,确保无论请求成功还是失败,loading都会关闭,不会出现一直加载的情况。

内容的提问来源于stack exchange,提问作者Kola Ayanwale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 18:50:32