vue3依赖注入的问题?

供给方组件:
image.png
注入方组件:
image.png
浏览器中可以正常展示:
image.png

但是如果在供给方组件中,更换ElMessage和provide的顺序,如下图:
image.png
浏览器中就无法正常渲染,并且控制台报警告:
image.png

请问这是什么原因呢?

备注:
"element-plus": "^2.3.12"
"vue": "^3.3.4"

阅读 1k
avatarAI BotBETA

这个问题涉及到Vue 3的依赖注入和组件提供(provide)与消费(inject)机制。在Vue 3中,使用provideinject可以实现跨组件的依赖注入。

首先,我们来解释一下为什么在供给方组件中更换ElMessageprovide的顺序会导致问题。

在第一个顺序中:

<template>
  <div>
    <供给方-组件 />
  </div>
</template>

<script>
import { ElMessage } from 'element-plus';
import供给方组件 from './供给方组件.vue';

export default {
  components: {
    供给方组件
  },
  setup() {
    ElMessage.install();
    return {
      msg: ElMessage('Hello World')
    };
  }
};
</script>

在这个顺序中,我们首先在setup()函数中安装了ElMessage,然后再返回一个msg对象。这样,在供给方组件中可以通过inject来获取到这个msg对象。

然而,如果我们更换了ElMessage.install()return的顺序,就会导致问题:

<template>
  <div>
    <供给方-组件 />
  </div>
</template>

<script>
import { ElMessage } from 'element-plus';
import供给方组件 from './供给方组件.vue';

export default {
  components: {
    供给方组件
  },
  setup() {
    return {
      msg: ElMessage('Hello World') // 在这个顺序下,安装ElMessage已经返回了msg对象,但是msg对象并没有被注入到供给方组件中,所以这里有一个错误
    };
  },
  mounted() {
    ElMessage.install(); // 这个顺序下,ElMessage是在挂载后才被安装的,已经晚了,所以这里也有一个错误
  }
};
</script>

这是因为ElMessage.install()实际上是在安装一个全局的插件,它会注册一些全局的实例方法和指令等。因此,它应该在setup()函数的开始处就被调用,这样它才能在setup()函数结束时(也就是组件初始化时)完成所有的安装和注册工作。如果将它放在setup()函数的末尾,那么在setup()函数执行完毕之前,这个全局插件的安装和注册工作实际上是没有完成的。这就导致了在供给方组件中无法正常获取到msg对象的问题。

另外,控制台报警告可能是因为你在组件被挂载(mounted)之后才调用ElMessage.install()。实际上,应该在组件初始化(created或beforeMount)的时候安装这个全局插件,而不是在挂载的时候。如果实在要在挂载时安装,那么应该在mounted钩子函数的开始处调用ElMessage.install(),以保证在组件挂载完毕后这个全局插件能够正常工作。但是在大多数情况下,建议在组件初始化的时候安装全局插件。

1 个回答

看了下,vue有个全局变量currentInstance,每次setup流程都会先将当前组件赋值给它,setup结束后再将currentInstance设为null

ElMessage.success这个方法会动态创建一个组件,也就是会走一遍setup流程,那这样ElMessage.success调用完成后,currentInstance就是null

provide时如果currentInstance为null就会报错,导致inject没有找到值

我感觉就是偷懒没做校验提示

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏