在 Vue 3 的 setup() 函数中,this 是 undefined。

Vue3的setup()函数中this为undefined,这是Composition API的重要改变。


替代方案包括:通过参数直接访问props和context(包含attrs、slots、emit等),使用解构语法简化写法。


相比Options API,Composition API不再依赖this,而是通过显式参数访问组件属性和方法,如用emit()替代this.emit,用ref替代this.el。


这种设计使代码更清晰明确,提升了TypeScript支持度,减少了this的"魔术性"访问。


在 Vue 3 的 setup() 函数中,thisundefined

这是 Vue 3 Composition API 的一个重要改变。


为什么 this 是 undefined?

setup() 函数中,组件实例尚未被完全创建,所以 this 不可用。


替代方案

1. 访问 Props

javascript 复制代码
import { defineProps } from 'vue';

export default {
  props: ['title'],
  setup(props) {  // props 作为第一个参数
    console.log(props.title);  // ✅ 正确
    // console.log(this.title);  // ❌ 错误!this 是 undefined
  }
};

2. 访问 Context(上下文)

javascript 复制代码
export default {
  setup(props, context) {  // context 作为第二个参数
    // context 包含以下属性:
    console.log(context.attrs);    // 非 props 的属性
    console.log(context.slots);    // 插槽
    console.log(context.emit);     // 触发事件的方法
    console.log(context.expose);   // 暴露公共属性
  }
};

3. 使用解构语法

javascript 复制代码
export default {
  setup(props, { attrs, slots, emit, expose }) {
    emit('myEvent', 'data');  // ✅ 触发事件
  }
};

4. 完整示例

javascript 复制代码
import { ref } from 'vue';

export default {
  props: ['initialCount'],
  emits: ['count-changed'],  // 声明自定义事件
  
  setup(props, { emit }) {
    const count = ref(props.initialCount || 0);
    
    const increment = () => {
      count.value++;
      emit('count-changed', count.value);  // 使用 emit 而不是 this.$emit
    };
    
    return {
      count,
      increment
    };
  }
};

与 Options API 的对比

javascript 复制代码
// Options API (Vue 2 / Vue 3 兼容)
export default {
  mounted() {
    console.log(this.$el);      // ✅ 可以访问
    console.log(this.$props);   // ✅ 可以访问
    this.$emit('event');        // ✅ 可以访问
  }
};

// Composition API
export default {
  setup(props, { emit }) {
    onMounted(() => {
      // console.log(this.$el);  // ❌ 错误!this 是 undefined
      console.log(props);        // ✅ 使用 props 参数
      emit('event');             // ✅ 使用 context.emit
    });
    
    // 如果需要访问模板引用,使用 ref
    const myElement = ref(null);
    
    return {
      myElement  // 在模板中通过 ref="myElement" 绑定
    };
  }
};

主要变化总结

Options API Composition API
this.$emit() emit() (从 context 获取)
this.$props props (setup 参数)
this.$attrs attrs (从 context 获取)
this.$slots slots (从 context 获取)
this.$el 模板引用 (ref)
this.$parent 避免使用,考虑 Provide/Inject

这种设计让代码更加明确,减少了 this 的魔术性,提高了 TypeScript 的支持度。

相关推荐
林恒smileZAZ2 小时前
vue对接海康摄像头-H5player
前端·javascript·vue.js
小安同学iter2 小时前
Vue3 进阶核心:高级响应式工具 + 特殊内置组件核心解析
前端·javascript·vue.js·vue3·api
Roc.Chang2 小时前
Vue 3 setup 语法糖 computed 的深度使用
前端·javascript·vue.js
淡笑沐白2 小时前
Vue3基础语法教程
前端·javascript·vue.js
一 乐2 小时前
景区管理|基于springboot + vue景区管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
Sylus_sui2 小时前
企业级Axios封装实战指南
vue.js
幽络源小助理2 小时前
SpringBoot+Vue大型商场应急预案管理系统源码 | Java安全类项目免费下载 – 幽络源
java·vue.js·spring boot
JIngJaneIL2 小时前
基于java + vue连锁门店管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
毕设十刻3 小时前
基于Vue的养老服务平台85123(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js