如何在Vue v-for循环中高效获取Firestore用户数据
方案可行性结论
你修改的Firestore查询方案可以提升页面加载速度,但当前写法存在逻辑缺陷无法正常运行,且还有比请求Firestore性能更高的优化方案。
现有修改版无法运行的原因
你写的filteredInfo是异步方法,Firestore的get()接口返回的是Promise对象,你在then回调里的返回值并不会被传递到模板调用处,模板拿到的是Promise而非实际用户数据,因此无法渲染。
最优优化方案(无需额外请求,性能最高)
你已经持有全量users数组,完全不需要额外调用Firestore接口,只需要提前把users数组转成以用户ID为key的映射对象,后续查找复杂度直接降到O(1),比发网络请求的方案性能高得多:
- 提前构建用户ID映射:在你获取到全量
this.users的逻辑后,新增一步转映射的逻辑:
this.userMap = this.users.reduce((map, user) => { map[user.id] = user return map }, {});
- 简化模板逻辑,删除多余v-for循环(用户ID唯一,filter返回的数组最多1个元素,完全不需要循环):
<span v-if="userMap[props.row.userId]?.skills?.length" style="display:inline;"> <v-popover> <i class="fad fa-briefcase"></i> <template slot="popover"> <span v-for="z in userMap[props.row.userId].skills" :key="z.title">{{z.title}} / </span> </template> </v-popover> </span>
若坚持使用Firestore查询的调整方案
如果你的场景不需要加载全量users数组,可按如下方式调整:
- 在data中声明缓存对象,避免同一个用户重复发起请求:
data() { return { queriedUsers: {} } }
- 改造异步查询逻辑:
async getSkillsByUserId(userId) { // 已查询过的用户直接返回缓存数据 if (this.queriedUsers[userId]) return this.queriedUsers[userId] const doc = await fb.usersCollection.doc(userId).get() const userData = doc.data() || {} this.queriedUsers[userId] = userData return userData }
- 模板配合异步判断处理加载状态,Vue3可搭配Suspense组件使用,Vue2建议优先使用前面的映射方案减少异步复杂度。
内容的提问来源于stack exchange,提问作者Greg Fielding
相关产品推荐
相关产品推荐

