You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue+Pinia+Firebase Firestore:避免多ID查询数据被覆盖

解决方案

要实现不同patientid的支付数据不被覆盖,你需要调整Mainpayments的数据结构,并修改getPayments方法中的赋值逻辑,同时处理Firestore实时监听的重复订阅问题。

方案1:使用对象存储(推荐,查找高效)

将Mainpayments改为键值对结构,key为patientid,value为对应支付数据数组,这样可以直接通过patientid快速定位并更新数据。

修改代码:

  1. 调整state中的结构:
state: () => {
  return {
    loadingPayments: false,
    payments: [],
    Mainpayments: {}, // 改为对象,键是patientid,值是支付数组
    transition: '',
    dayPayments: [],
    selectedDate: today(),
    paymentSubscriptions: {} // 存储每个patientid的监听取消函数,避免重复订阅
  }
},
  1. 更新getPayments方法:
async getPayments(id) {
  // 若已监听该patientid,先取消之前的监听
  if (this.paymentSubscriptions[id]) {
    this.paymentSubscriptions[id]()
  }

  paymentsCollectionQuery = query(paymentsCollectionRef, where("patientid", "==", id), orderBy("date", "desc"))
  this.loadingPayments = true

  // 保存新的监听取消函数
  this.paymentSubscriptions[id] = onSnapshot(paymentsCollectionQuery, (querySnapshot) => {
    const payments = []
    querySnapshot.forEach((doc) => {
      let payment = {
        id: doc.data().id,
        details: doc.data().details,
        date: doc.data().date,
        currencyhavetopay: doc.data().currencyhavetopay,
        currencypaid: doc.data().currencypaid,
        moneyhavetopay: doc.data().moneyhavetopay,
        moneypaid: doc.data().moneypaid,
        tooth: doc.data().tooth,
        doctor: doc.data().doctor,
        patientid: doc.data().patientid,
      }
      payments.push(payment)
    })

    // 直接赋值,存在则更新,不存在则新增
    this.Mainpayments[id] = payments
    this.loadingPayments = false
  }, error => {
    console.log('error', error.message)
    this.loadingPayments = false
  })
},

方案2:使用数组存储(保持顺序,适合遍历场景)

如果需要保持patientid的查询顺序,可以将Mainpayments改为数组,每个元素包含patientid和对应的payments数组。

修改代码:

  1. 调整state中的结构:
state: () => {
  return {
    loadingPayments: false,
    payments: [],
    Mainpayments: [], // 结构:[{ patientid: 'xxx', payments: [...] }, ...]
    transition: '',
    dayPayments: [],
    selectedDate: today(),
    paymentSubscriptions: {} // 存储监听取消函数
  }
},
  1. 更新getPayments方法:
async getPayments(id) {
  // 取消已有监听
  if (this.paymentSubscriptions[id]) {
    this.paymentSubscriptions[id]()
  }

  paymentsCollectionQuery = query(paymentsCollectionRef, where("patientid", "==", id), orderBy("date", "desc"))
  this.loadingPayments = true

  this.paymentSubscriptions[id] = onSnapshot(paymentsCollectionQuery, (querySnapshot) => {
    const payments = []
    querySnapshot.forEach((doc) => {
      let payment = {
        id: doc.data().id,
        details: doc.data().details,
        date: doc.data().date,
        currencyhavetopay: doc.data().currencyhavetopay,
        currencypaid: doc.data().currencypaid,
        moneyhavetopay: doc.data().moneyhavetopay,
        moneypaid: doc.data().moneypaid,
        tooth: doc.data().tooth,
        doctor: doc.data().doctor,
        patientid: doc.data().patientid,
      }
      payments.push(payment)
    })

    // 查找是否已有该patientid的条目
    const existingIndex = this.Mainpayments.findIndex(item => item.patientid === id)
    if (existingIndex !== -1) {
      // 更新已有条目
      this.Mainpayments[existingIndex].payments = payments
    } else {
      // 添加新条目
      this.Mainpayments.push({ patientid: id, payments })
    }

    this.loadingPayments = false
  }, error => {
    console.log('error', error.message)
    this.loadingPayments = false
  })
},

额外注意事项

  • 为避免内存泄漏,在组件卸载或不再需要监听时,调用取消监听的方法:
actions: {
  cancelAllSubscriptions() {
    Object.values(this.paymentSubscriptions).forEach(unsubscribe => unsubscribe())
    this.paymentSubscriptions = {}
    // 可选:清空Mainpayments
    // this.Mainpayments = {} 或 []
  }
}

在组件中:

import { onUnmounted } from 'vue'
import { useStorePayments } from '@/stores/storePayments'

const storePayments = useStorePayments()

onUnmounted(() => {
  storePayments.cancelAllSubscriptions()
})

内容的提问来源于stack exchange,提问作者omar jasim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 01:45:43