如何解决Vuex与依赖其状态的JS模块之间的循环依赖问题
解决方案
方案1:运行时动态引入store(改动最小)
ES 模块的循环依赖问题只出现在静态导入解析阶段,你可以把store的导入逻辑放到类方法运行时再执行,此时两个模块的导出已经完成,不会触发循环依赖报错:notifications.js修改为:
class Notification { constructor(options) { this.name = options.name // 运行时才加载store,避免静态导入的循环依赖 const store = require('./store.js').default this.state = store.state } } export default Notification
修改后原来的调用代码可以直接去掉state传参,不需要额外修改store侧的逻辑:
// store里的调用代码 new Notification({ name: 'notificationName' })
方案2:静态注入store实例(更适合大型项目)
如果你的Notification类多处用到store的能力(比如还要调用commit、dispatch),可以给类加静态注入方法,在store初始化完成后一次性注入实例,后续所有实例都可以直接复用:notifications.js修改为:
class Notification { // 静态存储store实例 static store = null // 提供注入入口 static injectStore(storeInstance) { Notification.store = storeInstance } constructor(options) { this.name = options.name this.state = Notification.store.state // 后续还可以直接用Notification.store.commit/dispatch } } export default Notification
在store.js初始化完成后调用一次注入逻辑即可:
import { createStore } from 'vuex' import Notification from './notifications.js' const store = createStore({ // 原有store配置 actions: { someAction() { // 直接调用,无需传任何store相关参数 new Notification({ name: 'notificationName' }) } } }) // 初始化完成后注入store,仅需执行一次 Notification.injectStore(store) export default store
这个方案的耦合度更低,后续扩展Notification的store相关能力不需要修改任何调用侧的代码,维护性更好。
方案3:抽离公共依赖(适合更复杂的场景)
如果后续两个模块的依赖逻辑更复杂,可以把共同依赖的状态逻辑抽成单独的公共模块,store和notification都依赖这个公共模块,从根源上避免循环依赖。
内容的提问来源于stack exchange,提问作者AlekseyHoffman
相关产品推荐
相关产品推荐

