<script setup> 和在 <script> 中使用 setup() 函数有什么区别
在 Vue 3 的 Composition API 中,使用 <script setup>
和在 <script>
中使用 setup() 函数有本质区别。
script setup 语法糖写法
<script setup>
是一种语法糖的写法。
<script setup>
// 组合式 API 代码直接写在这里
import { ref } from 'vue'
const count = ref(0)
</script>
-
特点:
编译器宏支持:自动暴露顶层变量(无需 return)
更简洁:减少样板代码
自动注册组件:导入的组件可直接在模板使用
编译器优化:更好的性能(编译时转换)
支持顶层 await:
<script setup>
const data = await fetchData() // 直接使用
</script>
-
特殊宏:
defineProps() / defineEmits():定义 props/emits
defineExpose():暴露组件属性
useSlots() / useAttrs():获取 slots/attrs
2. setup() 函数(传统写法)
<script>
export default {setup() {// 需要手动返回模板使用的数据const count = ref(0)return { count }}
}
</script>
-
特点:
显式返回:必须 return 模板需要的变量
手动处理上下文:通过参数获取
props/context
无法使用顶层 await:需在异步函数内使用
兼容 Options API:可与
data/methods
等混用
整理如下:
- 特性 script setup | setup() 函数
- 代码量: 更简洁(减少 ~30% 代码)| 需要显式 return
- 变量暴露: 顶层变量自动暴露 | 需手动返回
- 组件注册: 自动注册导入的组件 | 需在 components 选项声明
- Props/Emits 定义: 通过 defineProps/defineEmits 宏 | 通过函数参数 props/context 获取
- TypeScript 支持: 更好的类型推断 | 类型声明较复杂
- 顶层 await: 支持 | 不支持
- 上下文访问: 通过 useAttrs()/useSlots() | 通过 setup(props, context) 参数
代码示例对比
使用 script setup
<script setup>
import { ref } from 'vue'
import ChildComp from './ChildComp.vue'const count = ref(0)
defineProps({ msg: String })
</script><template><ChildComp @click="count++" />{{ msg }}: {{ count }}
</template>
使用 setup() 函数
<script>
import { ref } from 'vue'
import ChildComp from './ChildComp.vue'export default {components: { ChildComp },props: ['msg'],setup(props) {const count = ref(0)return { count } // 必须返回}
}
</script><template><ChildComp @click="count++" />{{ msg }}: {{ count }}
</template>
何时选择?
推荐 <script setup>
:
新项目首选,更简洁、性能更好,官方推荐写法。
考虑 setup() 函数:
需要兼容 Options API 或特殊逻辑(如动态组件名)。
注意:<script setup>
是编译时语法糖,最终会被转换为标准的 setup() 函数。