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
相关产品推荐
相关产品推荐

