Vue3如何获取当前组件实例?解决setup内无this的问题
Vue3 中实现原Vue2 全局消息调用效果的方法
你之前在Vue2中能通过this.$message触发消息提示,本质是依靠组件实例的this指向,拿到挂载在原型链上的全局方法。但根据Vue3官方文档说明:
在
setup()内部,this不会指向当前活动实例。由于setup()在其他组件选项被解析前就会被调用,因此setup()内部的this与其他选项中的this行为差异很大,当将setup()与其他Options API搭配使用时可能会造成混淆。
另外补充一点:ElMessage是函数式调用组件,本身不需要通过app.use全局注册才能使用,你之前在main.js中写的app.use(ElMessage)属于冗余配置,无法直接在setup中被this感知到。
以下是可落地的几种实现方案:
- 日常开发首选:直接按需导入ElMessage调用
这是Element Plus官方推荐的写法,无额外配置成本,对Tree-shaking友好,传入的参数配置和你原来的Vue2写法完全兼容:// home.vue import { ElMessage } from 'element-plus' export default { setup() { // 直接调用即可触发对应消息提示 ElMessage({ showClose: true, message: 'Success Message', type: 'success', }) } } - 适配Options API习惯:全局挂载属性保留this调用能力
如果你维护的老项目大量使用Options API,不想改动原有组件的this调用写法,可以在main.js中将ElMessage挂到全局属性上,逻辑和Vue2的原型挂载完全对齐:
这种配置下,传统Options API组件可以完全复用原来的调用写法,不需要修改业务逻辑:// main.js import { createApp } from 'vue' import App from './App.vue' import { ElMessage } from 'element-plus' const app = createApp(App) // 替代Vue2中 Vue.prototype.$message 的挂载逻辑 app.config.globalProperties.$message = ElMessage app.mount('#app')
注意:这种全局挂载的属性,不推荐在setup内部强行通过实例代理获取调用,相比直接导入会增加不必要的逻辑复杂度。// home.vue export default { methods: { handleSubmit() { // 这里的this行为和Vue2保持一致 this.$message({ showClose: true, message: 'Success Message', type: 'success', }) } } } - 非首选补充:setup中类this调用的实现方式
如果你一定要在setup中使用接近this的调用感,可以通过getCurrentInstance拿到组件代理对象后调用,但这种写法会让setup逻辑混入和响应式无关的实例获取代码,不建议作为通用开发规范:// home.vue import { getCurrentInstance } from 'vue' import { ElMessage } from 'element-plus' export default { setup() { const { proxy } = getCurrentInstance() const handleClick = () => { proxy.$message({ showClose: true, message: 'Success Message', type: 'success', }) } } }
内容的提问来源于stack exchange,提问作者Muhammad Lahin
相关产品推荐
相关产品推荐

