Vue中computed计算属性返回的星级评分总值无法在页面正常显示问题
核心问题
你遇到的问题本质是同步的computed属性无法捕获异步操作的返回结果:
- Firebase的
get()请求是异步执行的,computed里的代码会先执行完return totalValue(此时值还是初始的0),等Firebase接口返回数据后才会执行then里的累加逻辑,所以页面始终拿到的是初始值,外层的console.log也会先打印0。 - computed设计用于处理同步的响应式数据计算,不适合承载异步请求逻辑。
修复方案
把异步评分统计逻辑从computed移到生命周期钩子中,把总评分定义为响应式的data变量:
1. 调整data定义
在data的return里新增totalRating响应式变量:
data() { return { // 原有变量保持不变 totalRating: 0, // 新增总评分变量 } },
2. 删除computed里的totalRating方法,新增created生命周期钩子
把Firebase查询逻辑放到created中,查询完成后给this.totalRating赋值,注意用箭头函数避免this指向错误:
created() { this.getTotalRating() }, methods: { async getTotalRating() { let totalValue = 0 const querySnapshot = await firebase .firestore() .collection("reviews") .where("productId", "==", this.$route.params.id) .get() // 原有代码里get传参是多余的,不需要传参数 querySnapshot.forEach(doc => { totalValue += doc.data().rating }) this.totalRating = totalValue } },
3. 可选优化:开启实时更新
如果需要新增评论后总评分自动同步,把get()替换为onSnapshot实时监听即可:
getTotalRating() { firebase .firestore() .collection("reviews") .where("productId", "==", this.$route.params.id) .onSnapshot(querySnapshot => { let totalValue = 0 querySnapshot.forEach(doc => { totalValue += doc.data().rating }) this.totalRating = totalValue }) }
其他注意点
原有template不需要做任何修改,依然可以用{{ totalRating }}展示总评分值,后续要计算平均评分的话,可以保留一个computed属性用this.totalRating / this.resultCount计算即可。
内容的提问来源于stack exchange,提问作者Ruzna Rizvi
相关产品推荐
相关产品推荐

