setup 中获取组件实例
Vue 3 setup 函数中获取组件实例的方法
问题
Vue 3 的 setup 函数中 this 是 undefined,如何获取组件实例?
解答
使用 getCurrentInstance
import { getCurrentInstance, onMounted } from 'vue'
export default {
setup() {
// 获取当前组件实例
const instance = getCurrentInstance()
// proxy 是组件的公开实例,类似 Vue 2 的 this
const proxy = instance?.proxy
onMounted(() => {
// 访问组件属性
console.log(proxy?.$el)
console.log(proxy?.$attrs)
console.log(proxy?.$slots)
})
return {}
}
}
在 <script setup> 中使用
<script setup>
import { getCurrentInstance, onMounted } from 'vue'
const instance = getCurrentInstance()
onMounted(() => {
// 通过 proxy 访问实例属性
console.log(instance.proxy.$el)
})
</script>
更推荐的替代方案
<script setup>
import { useAttrs, useSlots, ref } from 'vue'
// 获取 attrs
const attrs = useAttrs()
// 获取 slots
const slots = useSlots()
// 获取 DOM 元素用 ref
const elementRef = ref(null)
</script>
<template>
<div ref="elementRef">内容</div>
</template>
getCurrentInstance 返回值结构
const instance = getCurrentInstance()
// instance 包含:
// - proxy: 组件公开实例(推荐使用)
// - ctx: 组件上下文
// - props: 组件 props
// - emit: 触发事件的方法
// - attrs: 非 props 的属性
// - slots: 插槽
关键点
setup中this是undefined,需要用getCurrentInstance()获取实例- 使用
instance.proxy访问公开实例,而不是直接用instance getCurrentInstance只能在setup或生命周期钩子中调用- 这是内部 API,官方不推荐在应用代码中使用,优先用
useAttrs、useSlots、ref等替代 - 生产环境中
instance.ctx会被精简,应使用proxy而非ctx
目录