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

相关推荐
DarkLONGLOVE14 小时前
快速上手 Pinia!Vue3 极简状态管理使用教程
javascript·vue.js
宸翰15 小时前
解决 uni-app App 端 vue-i18n 占位符丢失:封装跨端可用的 tf 格式化方法
前端·vue.js·uni-app
用户21366100357219 小时前
VueRouter进阶-动态路由与嵌套路由
前端·vue.js
暴走的小呆1 天前
Vue 2 中 Object 的变化侦测:从 getter/setter 到 Dep、Watcher、Observer
vue.js
英勇无比的消炎药1 天前
TinyVue v-auto-tip: 文本超长自动提示的优雅方案
vue.js
时光足迹2 天前
腾讯云 TRTC UniApp SDK 从入门到上线
前端·vue.js·uni-app
时光足迹2 天前
uni-app 里把加密视频嵌入页面播放?我分析了 4 种方案,只有 1 种接近完美
前端·vue.js·uni-app
时光足迹2 天前
JPush UniApp UTS 插件完全参考手册:API、事件与厂商通道一网打尽
vue.js·ios·uni-app
时光足迹2 天前
极光推送全攻略(下):uni-app 代码实现与 iOS 排查实战
vue.js·ios·uni-app
疯狂的魔鬼2 天前
一个"懂分寸"的文本省略组件是怎样炼成的
前端·vue.js·设计