问题
我使用lerna创建了两个vue3项目manage和client,manage项目使用npm link引入client项目,manage项目的APP组件引入client项目的HelloWorld组件,如果在HelloWorld中使用onMounted时,会提示onMounted内部使用了异步操作,但是onMounted仅仅运行了console.log()。
说一下我具体操作。
1.manage项目使用npm link client将client项目以包的形式引入其中
2.manager项目App组件使用client项目的组件HelloWorld App组件
<template>
<div>
<!-- <img alt="Vue logo" src="./assets/logo.png"> -->
<HelloWorld />
</div>
</template>
<script lang="ts">
import { HelloWorld } from 'client';
import { defineComponent } from 'vue';
// console.log('HelloWorld', HelloWorld.setup({msg: 'aaaa'}, {}));
export default defineComponent({
name: 'App',
components: {
HelloWorld
}
})
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
3.client项目的组件HelloWorld加入onMounted
HelloWrold组件代码
<template>
<div>
1111
</div>
</template>
<script lang="ts">
import { onMounted, defineComponent } from 'vue';
export default defineComponent({
name: 'HelloWorld',
props: {
msg: String
},
setup() {
onMounted(() => {
console.log('client');
});
return {}
}
})
</script>
client项目中的hellorWorld组件的onMounted会丢失组件对象,并爆出以下错误
我onMounted内部仅仅只行了console操作
问题复现
- 从上述仓库拉取代码
- 进入client和manage项目运行npm i
- 在client项目中运行sudo npm link
- 在manage项目中运行npm link client
- 在manage项目中运行npm run serve 上述操作完成即可看到上述错误,上述错误是因为在client项目中的HelloWorld中使用onMounted方法,导致解析时上下文环境丢失,instance对象为空。
已有调查
在onMounted前进行debugger
import { onMounted, defineComponent, getCurrentInstance } from 'vue';
export default defineComponent({
name: 'HelloWorld',
props: {
msg: String
},
setup() {
debugger
const instance = getCurrentInstance();
console.log('instance', instance);
onMounted(() => {
console.log('client');
});
return {}
}
})
getCuttentInstance函数运行时的文件如下,并且currentInstance对象为空
而setup运行完毕时对instance对象进行释放时的文件如下,并且currentInstance对象不为空
大家是否遇到过这个问题,如何解决的?
解决办法
从上述分析上来看,原因可能是因为HelloWorld进行解析时,内部使用的onMounted和getCuttentInstance相当于闭包,使用的是clien项目中的vue模块。
HelloWorld组件被引入manage项目使用,编译采用的是manage项目中的vue模块,所以编译和内部onMonted的vue模块环境不同,clien项目中的vue模块其实没有对应的instance。
解决思路就是借助lerna的模块可以共用主模块的node_modules,所以client和manage项目可以共用主模块node_modules下的vue包,此时问题解决完毕。