在 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 的支持度。

相关推荐
像我这样帅的人丶你还18 小时前
别再让JS耽误你进步了。
css·vue.js
@yanyu66618 小时前
07-引入element布局及spring boot完善后端
javascript·vue.js·spring boot
王霸天18 小时前
💥别再抄网上的Scale缩放代码了!50行源码教你写一个永不翻车的大屏适配
前端·vue.js·数据可视化
悟空瞎说18 小时前
深入 Vue3 响应式:为什么有的要加.value,有的不用?从设计到源码彻底讲透
前端·vue.js
SuperEugene21 小时前
前端通用基础组件设计:按钮/输入框/弹窗,统一设计标准|组件化设计基础篇
前端·javascript·vue.js·架构
我命由我1234521 小时前
在 React 项目中,可以执行 npm start 命令,但是,无法执行 npm build 命令
前端·javascript·vue.js·react.js·前端框架·json·ecmascript
aidou131421 小时前
Vue3自定义实现日期选择器(可单选或多选)
前端·javascript·vue.js·日期选择器·transition
忆琳1 天前
Vue3 优雅解决单引号注入问题:自定义指令 + 全局插件双方案
vue.js·element
Ruihong1 天前
放弃 Vue3 传统 <script>!我的 VuReact 编译器做了一次清醒取舍
前端·vue.js
蜡台1 天前
IDEA LiveTemplates Vue ElementUI
前端·vue.js·elementui·idea·livetemplates