Vue 组件中组件状态更改后计算方法不更新?快来看看两种解决方案
2024-03-27 12:12:44
Vue 组件中组件状态更改不再传播到计算方法
前言
在对 Vuex store 进行重构后,Vue 组件中的计算方法可能不再动态更新。本文将深入探讨这一问题,并提供两种有效的解决方案,以确保计算方法对 store 状态更改做出及时响应。
问题
当 store 使用 Promise 异步获取数据时,Promise 执行完后,store 状态会立即更新,从而触发计算方法的重新计算。然而,当 store 改用 async/await 异步风格时,异步操作会在事件循环的下一轮中执行,因此在计算方法执行时,store 状态尚未更新。
解决方案
为了解决这个问题,有两种解决方案:
1. 使用 Vuex Getter
Vuex Getter 是 store 中定义的函数,可以从 store 中获取状态。使用 Getter 可以在组件中获取 store 状态,而不需要直接访问 store。由于 Getter 是响应式的,因此当 store 状态发生变化时,Getter 的值也会自动更新,从而触发组件中依赖 Getter 的计算方法重新计算。
示例代码:
// store getter
export const currentUser = state => {
return state.users.current_user.id;
}
// component using getter
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters({
currentUser: 'currentUser',
}),
notifications() {
return Notification.query()
.where('target_type', 'User')
.where('target_id', this.currentUser)
.orderBy('created_at', 'desc').get()
},
},
}
2. 手动调用计算方法
可以通过在 store 状态发生变化时手动调用计算方法来解决这个问题。例如,可以在 store 的 mutation 中手动调用依赖该 mutation 的计算方法。
示例代码:
// mutation that commits the new user ID
export const setUserId = (state, id) => {
state.users.current_user.id = id;
this.currentUser_id(); // manually call the computed method
}
// component using manual invocation
export default {
computed: {
notifications() {
return Notification.query()
.where('target_type', 'User')
.where('target_id', this.currentUser_id)
.orderBy('created_at', 'desc').get()
},
currentUser_id() {
return this.$store.state.users.current_user.id
}
},
watch: {
currentUser_id() {
this.currentUser_id(); // manually call the computed method
}
},
}
结论
通过使用 Vuex Getter 或手动调用计算方法,可以确保计算方法在 store 状态更改时得到及时更新。这将解决组件中计算方法不动态更新的问题,从而保证组件状态与 store 状态始终保持一致。
常见问题解答
1. 为什么会出现这个问题?
当 store 使用 async/await 时,异步操作会在事件循环的下一轮中执行,导致在计算方法执行时,store 状态尚未更新。
2. Getter 和手动调用计算方法有什么区别?
Getter 是一种自动更新计算方法,而手动调用计算方法需要在 store 状态发生变化时手动触发。
3. 哪种解决方案更好?
使用 Getter 是一种更方便、更优雅的解决方案,因为它可以自动处理计算方法的更新。但是,在某些情况下,手动调用计算方法也可能是必要的,例如当计算方法依赖于其他计算方法时。
4. 是否还有其他解决方法?
可以使用 Vuex Actions 来处理异步操作,并确保在状态更改后触发计算方法。
5. 如何避免这个问题在将来发生?
在 store 中使用一致的异步处理方法,并了解 async/await 的行为,可以帮助避免此问题在将来发生。