Cannot access ‘store‘ before initialization at XXX文件【vue2到vue3升级】store与vueRouter循环引用

😖问题截图如下

在这里插入图片描述

import store from '@/store';
const { state } = store;//报错代码位置

😖问题排查思路(错误):一开始以为是项目缺失初始化store代码,检查下来并没有;然后怀疑文件import顺序前后导致,排查下来也没有;
😖问题排查思路(错误):测试vue3可以直接引用带store的文件,怀疑vue2和vue3 router和store注册方式不同导致的。
😀问题排查思路:由于还没有实例化Vue,所以只能从main.jsx开始手动注释各个引用文件,搞清楚程序执行顺序(堆栈)

😀原因是循环引用,直接给问题如何解决

因为直接拿的Tdesign的项目,从入口文件出现了循环引用:main.jsx=>axiosInstance=>store=>permission=>router=>store
只需要在router里面不直接引用带store的组件就行,才有()=>import动态加载组件。
📖正确答案:

{
    path: '/Report/dashboard',
    name: '/Report/dashboard',
    component: () => import('@/pages/Report1/dashboard/base/index.vue'),
    meta: { title: '腾讯的数据大屏' },
},

😅在vue2项目下,下面两种提前引入文件的写法都会出现标题中的报错:

import DashboardBase from ‘@/pages/Report1/dashboard/base/index.vue’;

{
path: ‘/Report/dashboard’,
name: ‘/Report/dashboard’,
component: () => DashboardBase,
meta: { title: ‘腾讯的数据大屏’ },
},

import DashboardBase from ‘@/pages/Report1/dashboard/base/index.vue’;

{
path: ‘/Report/dashboard’,
name: ‘/Report/dashboard’,
component: DashboardBase,
meta: { title: ‘腾讯的数据大屏’ },
},

✨总结-循环引用会导致XXX文件未初始化

💫对比vue3项目时,没有这个报错的原因

在vue3中的router中,如果使用component: DashboardBase直接引用带store的组件,并不会报错
😖原因是:router直接引用store。但是没有store引用router这样的循环引用。

import store from '@/store';
const { state } = store;//报错代码位置
### Vue3 中 `Cannot access 'load' before initialization` 的报错原因 此问题的根本原因是变量声明的 **暂时性死区 (Temporal Dead Zone, TDZ)**[^2]。当尝试在使用 `let` 或 `const` 声明变量之前访问该变量时,JavaScript 引擎会抛出此类错误。 #### 错误分析 在 JavaScript 中,`var` 和 `let/const` 存在不同的作用域行为和提升机制: - 使用 `var` 声明的变量会在其作用域内被提前声明并初始化为 `undefined`,因此即使在其实际声明位置前访问也不会引发运行时错误。 - 而对于 `let` 和 `const`,它们仅会被提前声明到当前作用域中,但在真正执行到声明语句之前无法访问这些变量。这种状态被称为 **TDZ**。 如果代码中有如下逻辑,则会出现上述错误: ```javascript console.log(load); // 尝试在此处访问 load 变量 let load = true; // 实际声明的位置 ``` 由于 `load` 是通过 `let` 声明,在它正式声明之前的任何读取操作都会触发 `ReferenceError: Cannot access 'load' before initialization`。 --- ### 解决方案 以下是几种常见的解决方法来规避这个问题: #### 方法一:调整变量使用的顺序 确保在调用或引用某个由 `let` 或 `const` 定义的变量之前完成它的声明赋值过程。例如修改上面的例子为: ```javascript let load = true; console.log(load); ``` 这样可以有效避免进入 TDZ 并消除潜在的风险。 #### 方法二:改用 `var` 关键字(不推荐) 尽管可以用 `var` 替代 `let` 来绕过这个限制,但这并不是最佳实践,因为它可能会引入其他难以追踪的问题比如意外覆盖全局命名空间中的同名属性等风险。除非有特殊需求否则应尽量坚持现代语法习惯即优先选用 `let` 或者 `const` 进行局部范围内的数据定义工作。 #### 方法三:重构代码结构 重新设计程序流程使得所有依赖项都先准备好再继续后续处理步骤。例如利用函数封装或者条件判断等方式延迟某些动作直到所需资源完全可用为止: ```javascript function initializeLoad() { let load = fetchSomeData(); // 模拟异步加载或其他复杂计算场景下的情况 processWithLoadedValue(load); // 处理已成功获取的数据对象实例化后的实体成员函数调用链路正常运作下去即可实现预期目标效果啦😊 } initializeLoad(); ``` 以上例子展示了如何把原本暴露在外层环境里的直接变量替换成为内部私有的临时存储单元并通过参数传递给特定上下文中去消费从而达到隔离副作用的目的同时也解决了原生ES模块标准下关于import/export规范里提到过的循环依赖陷阱等问题哦😎 --- ### 总结 为了防止出现 `Cannot access 'X' before initialization` 类型的异常,请始终牢记以下几点原则: 1. 遵循正确的编码次序——先声明后应用; 2. 明确区分不同种类关键字之间的差异特性及其适用场合以便做出明智的选择; 3. 当遇到复杂的相互关联关系时考虑采用更高级别的抽象手段如工厂模式、单例模式等等技术策略加以应对优化整体架构质量水平不断提高效率降低成本消耗💪 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值