Vue3导入的.js组合式函数返回数组无法在setup内正常访问
问题原因分析
首先修正getOrders组合式函数中的笔误:你定义的加载函数名为load_orders,但代码中调用了不存在的load_errors(),返回值也写错成了load_errors,需要统一修正为load_orders。
你的问题本质是异步时序问题:
Firestore的onSnapshot是异步触发的实时监听函数,你在setup中同步调用load_orders()后立刻读取profits.value,此时Firestore的网络请求还未返回,监听回调尚未执行,profits还是初始的空数组。
模板能正常显示是因为profits是响应式ref,后续异步更新值后模板会自动刷新;但你定义的new_series是普通JS对象,初始化赋值后不会跟随profits更新,因此拿不到最新值。
修复步骤
1. 用计算属性包裹new_series实现响应式同步
将new_series改为计算属性,每次profits更新时自动重新计算值,适配ApexChart的响应式绑定要求:
// 组件内setup首先导入computed import { computed, onUnmounted } from 'vue' setup() { const { orders, orders_error, load_orders, profits } = getOrders() load_orders() // 用computed包裹,自动跟随profits更新 const new_series = computed(() => [{ name: 'series1', data: profits.value }]) return { new_series, orders, load_orders, orders_error, profits } }
如果你的ApexChart组件没有自动监听配置变化,只需额外加一个watch监听profits变化,手动触发图表重绘即可。
2. 修复getOrders中的隐藏问题
2.1 避免重复累加数据
onSnapshot每次触发新快照时,需要先清空原有profits数组,否则旧数据会和新数据累加,导致结果异常:
// getOrders内onSnapshot回调中修改 .onSnapshot((snap) => { let docs = snap.docs.map(doc => { return { ...doc.data(), id: doc.id } }) orders.value = docs let last = 0 // 先清空原有数据,避免重复累加 profits.value = [] orders.value.forEach(element => { profit = last + element.profit_cash last = profit profits.value.push(profit) }) })
2.2 避免内存泄漏
onSnapshot会返回一个取消监听的函数,组件卸载时需要主动调用取消监听,防止内存泄漏:
// getOrders内修改load_orders const load_orders = async () => { try { // 保存取消监听的函数 const unSubscribe = projectFirestore.collection('users') .doc(user) .collection('orders') .doc('845thfdkdnefnt4grirg') .collection('profits') .onSnapshot((snap) => { // 原有逻辑不变 }) return unSubscribe } catch (err) { orders_error.value = err.message } }
组件内卸载时调用:
setup() { // ...其他逻辑 let unSub = null load_orders().then(fn => unSub = fn) onUnmounted(() => { unSub?.() }) // ...return逻辑 }
内容的提问来源于stack exchange,提问作者Leonardo
相关产品推荐
相关产品推荐

