setup 函数在 Vue 3 中的作用是什么?什么时候会执行
文章目录
- 前言
- ✅ 一、`setup()` 函数的作用是什么?
- ✅ 二、`setup()` 什么时候执行?
- ✅ 三、`setup()` 的参数
- ✅ 四、`setup()` 中不能做什么?
- ✅ 五、常见用法示例
- ✅ 六、总结(适合背诵或面试回答)
- `<script setup>` 是 **Vue 3.2+ 推出的语法糖**
- ✅ 一句话总结:
- ✅ 二、它能干什么?
- ✅ 三、核心特性与优势
- ✅ 四、与 `defineComponent + setup()` 对比
- ✅ 五、defineProps 和 defineEmits 示例
- ✅ 六、何时应该用 `<script setup>`?
- 🧠 面试总结推荐回答
前言
setup()
函数是 Vue 3 中 Composition API 的核心入口,它在组件生命周期中扮演了非常关键的角色。
✅ 一、setup()
函数的作用是什么?
setup()
是在组件创建之前执行的一个初始化函数,用来:
功能类别 | 作用简述 |
---|---|
响应式状态声明 | 创建 ref 、reactive 等响应式变量 |
逻辑封装 | 封装业务逻辑为函数(或导入 composables) |
生命周期注册 | 使用 onMounted 、onUnmounted 等注册生命周期逻辑 |
计算属性 | 使用 computed() 定义依赖状态的衍生值 |
props & emit | 接收组件的 props,并通过 emit 触发自定义事件 |
返回模板绑定对象 | 返回的数据/方法可以直接在模板 <template> 中使用 |
✅ 二、setup()
什么时候执行?
setup()
会在 组件初始化 时(比created
更早)执行 一次,并且只执行一次。
执行顺序如下:
beforeCreate -> setup() -> created -> beforeMount -> mounted
⚠️ 注意:在
setup()
中不能访问this
,因为组件实例还未创建完成。
✅ 三、setup()
的参数
setup(props, context) {// props 是只读的响应式对象// context 包含三个属性:attrs、slots、emit
}
参数 | 类型 | 说明 |
---|---|---|
props | 响应式 | 传入组件的 props,不能解构(会失去响应式) |
context | 普通对象 | 包含 attrs (非 props)、slots 、emit 等辅助项 |
✅ 四、setup()
中不能做什么?
- ❌ 不能访问
this
,因为组件实例还没创建。 - ❌ 不能使用
data
、methods
、computed
(Options API 的写法)。 - ❌ 不建议直接修改 props(它是只读响应式的)。
✅ 五、常见用法示例
import { defineComponent, ref, onMounted } from 'vue'export default defineComponent({props: {title: String},setup(props, { emit }) {const count = ref(0)const increment = () => {count.value++emit('update', count.value)}onMounted(() => {console.log('组件挂载', props.title)})return { count, increment }}
})
✅ 六、总结(适合背诵或面试回答)
setup()
是 Vue 3 中组件逻辑的统一入口,在组件创建前执行,用于定义响应式状态、逻辑封装、生命周期注册、事件触发等,是 Composition API 的核心支点。
<script setup>
是 Vue 3.2+ 推出的语法糖
是对 setup()
函数的简化写法,专为提高开发效率和代码可读性而设计。
✅ 一句话总结:
<script setup>
就是把setup()
函数**“自动内联展开”,省略defineComponent()
、return {}
等冗余写法,让你写的每一行代码自动在 setup 环境中执行**。
✅ 二、它能干什么?
等价于你自己手写的:
export default defineComponent({setup() {// ...return {}}
})
变成了这样👇:
<script setup>
import { ref } from 'vue'const count = ref(0)
function increment() {count.value++
}
</script><template><button @click="increment">{{ count }}</button>
</template>
✅ 三、核心特性与优势
特性 | 说明 |
---|---|
自动注册为 setup() | 所有代码都是在 setup() 中执行的,不用再写 setup() 函数 |
不需要 return | 所有声明的变量/函数,自动暴露给模板 <template> 使用 |
支持宏命令 | 提供 <script setup> 独有指令:defineProps() 、defineEmits() 等 |
更少的样板代码 | 不需要写 import { defineComponent } 、setup() , return {} 等 |
更强的类型推导 | 更好配合 TypeScript 使用 |
✅ 四、与 defineComponent + setup()
对比
对比项 | <script setup> | defineComponent + setup() |
---|---|---|
写法简洁性 | ✅ 更简洁、无样板代码 | ❌ 模板多 |
模板中变量自动暴露 | ✅ 自动暴露,无需 return | ❌ 需要手动 return |
TypeScript 类型推导 | ✅ IDE 更智能 | ✅ 支持但稍显繁琐 |
可读性 | ✅ 更易读 | ❌ 模板化程度高 |
灵活性(命名组件) | ❌ 不支持写 name 字段(需额外用 defineOptions) | ✅ 可以显式命名 |
✅ 五、defineProps 和 defineEmits 示例
<script setup lang="ts">
const props = defineProps<{ title: string }>()
const emit = defineEmits<{(e: 'update', value: number): void
}>()function click() {emit('update', 42)
}
</script>
✅ 六、何时应该用 <script setup>
?
场景 | 是否推荐用 <script setup> |
---|---|
Vue 3 + TypeScript 项目 | ✅ 强烈推荐 |
单文件组件 + 简洁逻辑 | ✅ 更高效 |
组件逻辑复杂,需要分离 | ✅ 可以拆分成 composables |
需要用 JSX | ❌ 不支持 <script setup> JSX |
迁移自 Vue 2 | ✅ 可逐步迁移简化 |
🧠 面试总结推荐回答
<script setup>
是 Vue 3.2 引入的 SFC 编译器语法糖,本质上是 setup 函数的展开,去掉了样板代码、提高了开发效率,自动暴露变量给模板、支持 defineProps/Emits,特别适合 TypeScript 项目与组合式逻辑拆分。