目录
一、setup() 的执行时机
-
setup()
在 组件实例创建之前 执行。 -
它的调用时机相当于 Vue2 的 beforeCreate 和 created 两个生命周期之间。
-
在这个阶段:
-
组件的
props
已经解析完成,可以直接使用; -
但此时组件实例还没有完全建立,因此在
setup()
中不能访问this
,this
会是undefined
。
-
简单来说,setup()
是 组件逻辑的入口函数,里面可以定义响应式数据、方法、计算属性,以及注册生命周期钩子等。
二、setup() 的函数签名
setup()
的函数定义大致如下:
setup(props, context) {
// 逻辑代码
return {
// 这里返回的内容会暴露给模板使用
}
}
它接收两个参数:
-
props:父组件传递的属性对象,具有响应性;
-
context:上下文对象,包含 attrs、slots、emit。
返回值可以是:
-
一个对象 —— 其中的属性和方法会直接暴露给模板;
-
一个渲染函数 —— 适用于高级场景,直接控制渲染。
三、props 参数
-
props
包含父组件传入的所有props
,并且是 响应式对象。 -
需要注意:不能直接用解构赋值,否则会丢失响应性。
setup(props) { console.log(props.title) // ✅ 正常 const { title } = props // ❌ 这样会丢失响应性 }
如果需要解构,可以使用
toRefs
或toRef
:import { toRefs } from 'vue' setup(props) { const { title } = toRefs(props) return { title } }
四、context 参数
context
是一个普通对象(非响应式),包含三个常用属性:
属性 | 作用 | 对应 Vue2 写法 |
---|---|---|
attrs | 透传的非 props 特性 | this.$attrs |
slots | 插槽对象 | this.$slots |
emit | 触发自定义事件的方法 | this.$emit |
示例:
setup(props, { attrs, slots, emit }) {
console.log(attrs) // 透传的 attribute
console.log(slots) // 插槽内容
emit('update', 123) // 触发事件
}
五、一个完整示例
<template>
<h1>{{ title }}: {{ count }}</h1>
<button @click="increment">+1</button>
</template>
<script>
import { ref, toRefs } from 'vue'
export default {
props: {
title: String
},
emits: ['update'],
setup(props, { emit }) {
const { title } = toRefs(props)
const count = ref(0)
function increment() {
count.value++
emit('update', count.value)
}
return { title, count, increment }
}
}
</script>
运行效果:
-
父组件传入的
title
会显示; -
点击按钮可以触发计数加 1;
-
同时通过
emit
触发父组件的事件。
六、总结
-
setup()
是 Vue3 组件逻辑的入口; -
它在 beforeCreate 和 created 之前执行;
-
接收两个参数:
-
props
:响应式的父组件传参; -
context
:非响应式对象,包含 attrs、slots、emit;
-
-
返回的对象会暴露给模板直接使用。
在日常开发中,建议优先使用 <script setup>
语法糖,它本质上就是把 setup()
的逻辑写得更简洁,开发体验更好。