在 Vue3 中,setup
函数是组合式 API 的核心入口,它承担着组件逻辑组织、状态管理和通信桥梁的重要作用,是连接组合式 API 与组件实例的关键纽带。其主要作用可归纳为以下几点:
1. 作为组合式 API 的“逻辑容器”
setup
函数是组合式 API 的起点,所有组合式 API(如 ref
、reactive
、onMounted
等)都需要在 setup
内部或其调用的函数中使用。它允许将组件的数据、方法、生命周期逻辑等聚合在一起,解决了 Vue2 选项式 API 中逻辑碎片化的问题。
例如,将数据定义、事件处理和生命周期逻辑集中在 setup
中:
import { ref, onMounted } from 'vue'
export default {
setup() {
// 数据定义
const count = ref(0)
// 方法定义
const increment = () => {
count.value++
}
// 生命周期逻辑
onMounted(() => {
console.log('组件挂载完成,初始count为', count.value)
})
// 暴露给模板使用
return { count, increment }
}
}
2. 替代 Vue2 的 beforeCreate
和 created
钩子
setup
的执行时机非常特殊:在组件实例创建后、props 解析完成,且在 beforeCreate
钩子之前执行(介于 beforeCreate
和 created
之间)。因此,它可以直接替代这两个钩子的功能,处理组件初始化阶段的逻辑(如数据初始化、请求初始数据等)。
在 Vue2 中需要写在 created
中的逻辑,在 Vue3 中可直接放在 setup
里:
// Vue2 写法
export default {
data() { return { data: null } },
created() {
this.fetchData() // 初始化时请求数据
},
methods: { fetchData() {} }
}
// Vue3 setup 替代写法
export default {
setup() {
const data = ref(null)
// 相当于 created 中的逻辑
const fetchData = async () => {
data.value = await api.getData()
}
fetchData() // 直接执行初始化逻辑
return { data }
}
}
3. 提供组件通信的入口
setup
函数接收两个参数,用于处理组件的外部通信:
props
:组件接收的 props 数据(响应式,且会随父组件传递的值自动更新)。context
:包含组件的上下文信息,如attrs
(非 props 属性)、emit
(触发父组件事件)、slots
(插槽内容)等。
示例:通过 setup
处理 props 和事件通信
export default {
props: {
initialCount: { type: Number, default: 0 }
},
setup(props, context) {
// 使用 props 数据(响应式)
const count = ref(props.initialCount)
// 触发父组件事件(通过 context.emit)
const reset = () => {
count.value = 0
context.emit('count-reset', 0) // 通知父组件
}
return { count, reset }
}
}
4. 隔离组件状态与逻辑复用
setup
函数内部定义的变量和函数,默认仅在当前组件生效,不会污染全局或其他组件。这种隔离性为逻辑复用提供了便利——可以将 setup
中的部分逻辑抽离为独立的工具函数(如 useXXX
形式的组合函数),实现跨组件复用。
例如,抽离一个计数器逻辑:
// 复用逻辑:useCounter.js
import { ref } from 'vue'
export function useCounter(initialValue = 0) {
const count = ref(initialValue)
const increment = () => count.value++
return { count, increment }
}
// 组件中使用
import { useCounter } from './useCounter'
export default {
setup() {
const { count, increment } = useCounter(10) // 复用逻辑
return { count, increment }
}
}
5. 与模板和渲染函数的连接
setup
函数的返回值(通常是一个对象)会暴露给组件的模板或渲染函数,供视图层使用。返回的响应式数据(如 ref
、reactive
创建的数据)在模板中会自动解包,无需手动访问 .value
。
如果返回的是一个函数,则该函数会被视为组件的渲染函数:
import { h, ref } from 'vue'
export default {
setup() {
const count = ref(0)
// 返回渲染函数
return () => h('div', `Count: ${count.value}`)
}
}
注意事项
setup
中无法访问this
(此时组件实例尚未完全创建),需通过props
和context
参数获取外部信息。setup
是同步执行的,若需异步逻辑,可配合async/await
,但此时需返回一个 Promise 或使用<Suspense>
组件包裹。- 在单文件组件(SFC)中,若使用
<script setup>
语法糖,会自动替代setup
函数的功能,进一步简化代码。
总结
setup
函数是 Vue3 组合式 API 的“中枢”,它统一了组件的逻辑组织方式,替代了传统的初始化钩子,提供了组件通信的接口,并为逻辑复用奠定了基础。其设计核心是让开发者能更灵活地按业务逻辑拆分代码,而非被选项式 API 的固定结构束缚。