如何通过Firebase的onSnapshot监听器更新Vue的ref值?
问题原因
onSnapshot 是异步监听方法,外部打印为空是同步代码执行顺序导致的:
- 调用
getCollection时,JS会先同步执行所有顶层代码:初始化documentsArray为null、调用onSnapshot注册监听、执行外部的console.log、最后返回两个ref。这时候Firebase还没完成数据请求,回调函数压根没触发,所以打印出来的就是初始的空值/null。 - 只有等Firebase后台请求数据完成、或者后续数据发生变更时,
onSnapshot传入的回调才会被触发,这时候才会给documentsArray.value赋值,所以回调内部的打印能拿到最新数据。
正确使用方式
因为documentsArray是Vue的响应式ref,你不需要同步拿到它的值,直接在Vue模板、计算属性、或者其他watch监听里用就行,值更新后会自动触发响应式更新:
示例用法:
<script setup lang="ts"> import getCollection from '@/composables/getCollection' const { documentsArray, error } = getCollection('你的集合名') </script> <template> <!-- 直接使用即可,数据加载完成后会自动渲染 --> <div v-if="error">{{ error }}</div> <div v-for="item in documentsArray" :key="item.id"> {{ item.message }} </div> </template>
如果你需要在业务逻辑代码里监听值的变化,可以用watch或者watchEffect:
import { watch } from 'vue' watch(documentsArray, (newVal) => { if (newVal) { console.log('集合数据更新完成', newVal) } })
额外说明
你当前的初始值设的是null,如果外部打印显示的是空数组,大概率是你后续其他业务逻辑给它赋值过空数组,核心监听逻辑本身没有问题,完全符合异步代码的执行规则。
内容的提问来源于stack exchange,提问作者TinyTiger
相关产品推荐
相关产品推荐

