Vue Composition API 从Firestore获取对象数组仅返回单条数据解决方案
问题原因
- ref使用不符合规范:通过
ref()创建的响应式变量,所有对值的读写操作都需要操作其.value属性,你直接对pinz变量赋值,相当于把整个ref响应式对象替换为普通数组,不仅丢失响应性,也属于错误用法。 - 数组内容被循环覆盖:在
forEach遍历中你写的pinz = [doc.data()],每遍历到一条文档就会把变量赋值为仅包含当前单条文档的新数组,循环结束后变量只会保留最后一条文档的内容,所以最终数组只有1个对象。
修正后的代码
推荐更简洁的写法,直接批量转换文档集合为数组赋值:
import { ref } from 'vue' // 响应式数组定义在函数外部,组件内可直接访问使用 const pinz = ref([]) const loadPinz = async () => { // 可选:加载前清空旧数据 pinz.value = [] const querySnapshot = await db.collection('pin').get() // 直接把所有文档转为数组赋值给ref的value属性 pinz.value = querySnapshot.docs.map(doc => doc.data()) // 打印要取value属性才能拿到实际数组 console.log(pinz.value) }
如果习惯用forEach遍历追加,写法如下:
const loadPinz = async () => { pinz.value = [] const querySnapshot = await db.collection('pin').get() querySnapshot.forEach(doc => { pinz.value.push(doc.data()) }) console.log(pinz.value) }
相关原理解释
- Vue3的
ref方法会对传入的基础类型、数组、普通对象做响应式包装,返回一个只有value属性的对象,所有对原始值的修改必须通过.value操作才会触发响应式更新,在<template>中使用时Vue会自动解包,不需要额外加.value。 - Firestore的
get()方法返回的querySnapshot的docs属性本身就是包含所有文档快照的数组,用map方法直接转换为数据数组是性能最优的写法,避免循环多次修改数组。
内容的提问来源于stack exchange,提问作者H_alt
相关产品推荐
相关产品推荐

