Vue 3 的 setup 函数中 this 为 undefined,因其在组件实例创建前执行,不绑定实例;需用 ref、reactive、emit 等组合式 API 替代 this 访问。

在 Vue 3 的 Composition API 中,setup 函数里访问 this 是 undefined,根本原因在于:setup 执行时组件实例尚未创建,而 this 指向的是组件实例。这不是 bug,是设计使然——Composition API 从底层就摒弃了选项式 API 的实例代理机制。
setup 是一个纯函数,不绑定组件实例
setup 在组件初始化早期(props 解析之后、实例创建之前)被调用,此时 Vue 还没构建出 this 所依赖的响应式代理对象和方法绑定环境。它只接收 props 和 context(含 emit、slots、attrs),不接收 this。
- 你不能在
setup里写this.count++或this.$refs.input - 所有逻辑必须基于
ref、reactive、computed、onMounted等组合式 API 显式声明 - 想访问 DOM 元素?用
ref()声明引用,配合onMounted获取
别再试图“找回 this”,要重构思维模式
很多开发者习惯性地想把选项式写法“平移”进 setup,比如:
setup() {<br> console.log(this); // undefined<br> this.name = 'Alice'; // 报错:Cannot set property 'name' of undefined<br> return {};<br>}
正确做法是彻底转向响应式声明:
- 用
const name = ref('Alice')替代this.name - 用
const count = ref(0)+count.value++替代this.count++ - 方法定义为普通函数,显式返回并暴露给模板:
const handleClick = () => { count.value++ }
那些你以为需要 this 的场景,都有 Composition API 对应解法
访问子组件或 DOM 元素?
用 ref 绑定,配合生命周期钩子:
-
const inputRef = ref(null)→ 模板中<input ref="inputRef"> onMounted(() => inputRef.value?.focus())
触发自定义事件?
用 context.emit(或解构出 emit):
-
const { emit } = context→emit('update:modelValue', newValue)
访问插槽或 attrs?
直接从 context 解构:
-
const { slots, attrs } = context,无需this.$slots或this.$attrs
过渡期小技巧:快速识别和修正 this 误用
如果你正从 Options API 迁移,可以这样自查:
- 把所有
this.xxx替换为xxx.value(如果是ref)或直接xxx(如果是reactive对象的属性) - 把
methods里的函数搬到setup内部定义,显式return出去 - 把
data转成ref/reactive,把computed转成computed(() => ...) - 遇到
this.$nextTick?改用nextTick(() => {...})(需从vue导入)

















