如何在Firestore查询前等待Pinia Store状态加载完成?
解决Vue+Pinia+Firestore刷新后查询失败的问题
问题核心是刷新页面时,组件查询逻辑执行早于Pinia Store的user_id初始化完成,导致查询用了空的user_id,最终失败。以下是几种可行的解决方式:
1. 监听user_id的变化动态执行查询
利用Vue的watch监听Pinia中user_id的变化,仅当user_id有效时才创建Firestore查询并订阅快照,同时记得在组件卸载时取消订阅避免内存泄漏:
<script setup> import { ref, watch, onUnmounted } from 'vue'; import { useSession } from '@/stores/session'; import { query, where, orderBy, limit, onSnapshot } from 'firebase/firestore'; const transactions = ref([]); const store = useSession(); let unsub = null; // 监听user_id变更,动态处理查询 watch( () => store.user_id, (newUserId) => { // 先取消之前的订阅(如果存在) if (unsub) { unsub(); unsub = null; } // 仅当user_id存在时执行查询 if (newUserId) { const q = query( colRef, // 确保colRef已正确指向Firestore集合 where("user_id", "==", newUserId), orderBy("created_at", "desc"), limit(30) ); unsub = onSnapshot(q, (snapshot) => { transactions.value = snapshot.docs.map(doc => ({ ...doc.data(), id: doc.id })); }); } else { // 无有效user_id时清空交易记录 transactions.value = []; } }, { immediate: true } // 立即执行一次,处理组件初始加载的情况 ); // 组件卸载时清理订阅 onUnmounted(() => { unsub?.(); }); </script>
2. 在Pinia Store中添加初始化状态标记
如果你的Store是从本地存储(如localStorage)恢复用户信息,可以在Store中添加一个isInitialized状态,确保Store初始化完成后再执行查询:
第一步:修改Pinia Store
import { defineStore } from 'pinia'; export const useSession = defineStore('session', { state: () => ({ user_id: null, isInitialized: false // 标记Store是否完成初始化 }), actions: { initSession() { // 从本地存储恢复用户ID const savedUserId = localStorage.getItem('user_id'); if (savedUserId) { this.user_id = savedUserId; } this.isInitialized = true; } } });
第二步:在应用入口初始化Store
在App.vue或项目入口文件中调用初始化方法:
<script setup> import { useSession } from '@/stores/session'; const sessionStore = useSession(); sessionStore.initSession(); </script>
第三步:组件中监听初始化状态+user_id
watch( () => [store.isInitialized, store.user_id], ([isInitialized, userId]) => { if (isInitialized && userId) { // 执行查询逻辑(同方案1中的查询代码) } }, { immediate: true } );
3. 在Store中监听Firebase Auth状态(如果用Firebase Auth)
如果你的用户ID来自Firebase Auth,直接在Store中监听Auth状态变化,自动同步user_id,组件只需监听user_id即可:
修改Pinia Store
import { defineStore } from 'pinia'; import { onAuthStateChanged } from 'firebase/auth'; import { auth } from '@/firebase/config'; export const useSession = defineStore('session', { state: () => ({ user_id: null }), actions: { setupAuthListener() { onAuthStateChanged(auth, (user) => { this.user_id = user?.uid || null; }); } } });
入口文件启动监听
<script setup> import { useSession } from '@/stores/session'; const sessionStore = useSession(); sessionStore.setupAuthListener(); </script>
内容的提问来源于stack exchange,提问作者Carlos Vidal
相关产品推荐
相关产品推荐

