依赖Vuex存储属性的Computed property为何不更新?
当reservation更新时(已确认更新,可通过模板中{{ reservation.id }}查看变化),以下计算属性reservationHashedId却未更新,请问原因是什么?
const reservation = computed(() => store.state.infoPaneReservation) const reservationHashedId = computed(() => { return reservation.hashedId ? reservation.hashedId : 'Unknown reservation' })
按照计算属性的逻辑,内部依赖变化时应该重新计算,但此处无效。直接在计算属性中引用存储属性能解决问题:
const reservation = computed(() => store.state.infoPaneReservation) const reservationHashedId = computed(() => { const reservation = store.state.infoPaneReservation // 这样写就生效了 return reservation.hashedId ? reservation.hashedId : 'Unknown reservation' })
但肯定有更优的实现方式吧?
问题原因
在Vue中,computed()返回的是Ref对象,而非直接返回目标值。模板中会自动为Ref解包,所以你在模板里用{{ reservation.id }}能正常看到更新;但在JavaScript代码里,必须通过.value属性才能访问到Ref内部的响应式值。
你最初的代码里直接访问reservation.hashedId,实际上是在访问Ref对象本身的hashedId属性(这个属性根本不存在),而非store.state.infoPaneReservation的hashedId。这段代码没有建立对reservation内部响应式值的依赖,所以当store.state.infoPaneReservation更新时,reservationHashedId不会触发重新计算。
而修改后的代码直接引用了store.state.infoPaneReservation这个响应式状态,能正确建立依赖,因此计算属性会正常更新。
优化实现方式
最规范的优化方式是在JavaScript中访问computed返回的Ref对象时,加上.value:
const reservation = computed(() => store.state.infoPaneReservation) const reservationHashedId = computed(() => { return reservation.value?.hashedId || 'Unknown reservation' })
如果不需要单独的reservation计算属性,也可以直接在reservationHashedId中引用状态,代码更简洁:
const reservationHashedId = computed(() => { return store.state.infoPaneReservation?.hashedId || 'Unknown reservation' })
两种写法都能正确建立响应式依赖,确保reservationHashedId在store.state.infoPaneReservation更新时自动重新计算。
内容的提问来源于stack exchange,提问作者Chuck Le Butt

