Vue 3 高频面试题:setup() 函数详解
主问题
问: Vue 3 中的 setup() 是什么?它的执行时机是什么?能做什么?
面试官追问(非常高频)
执行时机相关
- "setup 是在 beforeCreate 之前还是之后执行?"
- "setup 中能访问到 this 吗?为什么不能?"
- "setup 执行一次还是多次?"
内部机制与用途
- "为什么 setup 返回的值能在模板里用?"
- "setup 里能访问 props 和 context 吗?有什么区别?"
- "attrs、slots、emit 是从哪里来的?"
生命周期相关
- "Composition API 的生命周期钩子写在哪里?"
- "onMounted 为什么一定要在 setup 里调用?"
实践应用
- "如何使用 setup 封装一个组合式函数(composable)?"
- "在 setup 中如何使用 watch / computed?"
- "如何在 setup 中获取 template ref?"
参考答案(详细 + 面试可直接背)
1️⃣ setup 的定义
setup() 是 Composition API 的入口函数,用于:
- 声明响应式变量(ref/reactive)
- 声明计算属性(computed)
- 注册监听器(watch)
- 使用生命周期钩子(onMounted 等)
- 返回模板需要使用的数据/方法
- 执行组合式函数(composables)
2️⃣ setup 的执行时机
执行时机:
- 在 beforeCreate 之前执行
- 执行顺序:setup → beforeCreate → created
- 说明:setup 是整个组件初始化的最早阶段(在 Options API 之前)
面试官追问: setup 为什么这么早执行?
👉 因为 Composition API 的响应式系统需要在组件实例创建之前建立。
3️⃣ setup 里访问不到 this 的原因
回答关键点:
Vue 3 中,setup 在组件实例创建之前执行,因此:
- 此时 this 还未建立
- this 在 setup 中始终是 undefined
👉 Vue 3 设计上不建议你在 Composition API 中使用 this。 所有依赖 this 的逻辑都应该写在 Options API 或依赖 props/context。
4️⃣ setup 的参数:setup(props, context)
setup 接收两个参数:
✔ props
- 响应式的
- 但不是 Proxy,因为要保持对外只读
- 可以直接通过 props.xxx 获取
✔ context(上下文对象,不是响应式)
包含:
javascript
{
attrs, // 接收父组件传入但未声明的属性
slots, // 插槽
emit // 触发事件
}
示例:
javascript
setup(props, { attrs, slots, emit }) {
console.log(props.title)
emit('update')
}
5️⃣ setup 返回值为什么能在模板里使用?
因为 Vue 自动将 setup return 的内容加入到组件的渲染上下文(render context)中。
如果你返回:
javascript
return { count, double, increment }
模板可以直接使用:
html
<div>{{ count }}</div>
<button @click="increment">+</button>
6️⃣ setup 中使用生命周期钩子
Composition API 的生命周期钩子必须在 setup 中调用,比如:
javascript
import { onMounted, onUnmounted } from 'vue';
setup() {
onMounted(() => console.log('mounted'));
onUnmounted(() => console.log('unmounted'));
}
生命周期映射表:
| Options API | Composition API |
|---|---|
| mounted | onMounted |
| updated | onUpdated |
| unmounted | onUnmounted |
| created | ❌(被 setup 取代) |
7️⃣ setup 实战示例(包含常用能力)
vue:/Users/wangyahao/Desktop/项目/new/自动写小说/后端/111.md
<script setup>
import { ref, reactive, computed, watch, onMounted } from 'vue';
const count = ref(0);
const state = reactive({
user: { name: 'Alice' }
});
const double = computed(() => count.value * 2);
watch(count, (n, o) => {
console.log(`count changed from ${o} to ${n}`);
});
onMounted(() => {
console.log('Component mounted!');
});
function increment() {
count.value++;
}
</script>
面试亮点总结(背下直接加分)
- setup 是 Composition API 的核心入口
- 在 beforeCreate 之前执行,此时还没有组件实例
- setup 内不能访问 this(永远是 undefined)
- setup(props, context) 中的 context 只包含:attrs / slots / emit
- setup 返回的内容会暴露给模板
- 所有 Composition API 的生命周期钩子必须在 setup 调用
- setup 是组合式函数(composable)复用逻辑的核心