//a.js
console.log("before import b")
import {b} from "./b"
console.log("b is " + b)
export let a = b+1;
//b.js
console.log("before import a")
import {a} from "./a"
console.log("a is " + a)
export let b = a+1;
输出:
before import a
a is undefined
before import b
b is NAN
记一次组件导入报错的问题
在开发需求的过程,需要在一个新建页面的保存时, 点击按钮跳转到对应的详情页. 但是在实习操作中发现点击这个按钮唤起组件时浏览器却报错了.
乍一看这个报错,我还以为是因为组件的驼峰没有写好 注意: vue在导入组件的时候, 组件名称一定要为驼峰形式, 组件在标签使用时用-隔开,很多时候这个报错都是因为命名造成的 不过很可惜 这里并不是因为命名, 在检查了好几篇之后用打印的方式尝试看看 在SelectTypeAndCatalogDialog.vue这个页面中打印 导入的WorkOrderDetailDialog发现确实为undefined 于是往上层组件开始寻找问题:
发现在父组件中同时使用了这个两个组件 简单理解为 a(父) b(子) c(子) a调用了bc b调用了c, 发现WorkOrderDetailDialog其实在父组件和兄弟组件中都有调用 考虑可能是和引用的时候出错有关.仔细把两个组件都捋顺了一遍, 发现其实在WorkOrderDetailDialog组件中有调用一个panel组件 而在panel组件中又调用了SelectTypeAndCatalogDialog组件. 哦豁, 循环引用! 有问题! 整理整个组件调用的情况 得到如下图: 实际上, WorkOrderDetailDialog作为工单详情页还有递归调用的情况, 经过排查其实和递归组件问题无关,所以这里暂时就不做展开.
那么相互引用会存在什么问题呢? 这里就涉及到es6的import模块相互引用的问题: 这里引用阮一峰老师的例子:
输出:
这里有一个有趣的现象就是第一句输出并不是before import b,也就是虽然import语句在后面,但确会更早执行,当执行import b时,加载并运行b.js,从而第一句输出是before import a。 然后就是当运行b.js时,发现又需要import a.js,此时不会再去加载a.js了,而是认为整个a.js模块是{},所以a的值就是undefined了
那么同理 对于我所遇到的问题: SelectTypeAndCatalogDialog中有调用WorkOrderDetailDialog WorkOrderDetailDialog中有调用SelectTypeAndCatalogDialog
从项目结构来看, WorkOrderDetailDialog就相当于是a.js中的a了 所以在SelectTypeAndCatalogDialog中我们就取不到WorkOrderDetailDialog了
遇到了问题, 那应该怎么解决呢: 目前想到了三种解决方案并都测试有效:
好了这个问题的解决也让我加深了对循环引入的理解,受益良多 bye