以下是 Vue3 <script setup> 的 超详细说明,涵盖核心机制、使用场景和最佳实践:
1. 核心设计原理
- 编译时语法糖:
<script setup>会在编译阶段转换为标准的setup()函数,所有顶层绑定自动暴露给模板。 - 作用域隔离:内部代码默认在闭包中执行,避免污染全局作用域,同时通过编译器静态分析实现模板直接引用。
2. 响应式数据管理
- 自动解包:
ref在模板中无需.value,但在逻辑代码中仍需:<script setup> const count = ref(0) // 模板中直接写 {{ count }} console.log(count.value) // JS 中需 .value </script> - 响应式工具链:支持
reactive、computed、watch等组合式 API,与标准写法一致。
3. 组件通信
- Props 声明:使用
defineProps宏(支持运行时声明和 TypeScript 类型):<script setup> const props = defineProps({ title: String, size: { type: Number, default: 10 } }) // TS 写法 defineProps<{ title: string; size?: number }>() </script> - 事件发射:通过
defineEmits:<script setup> const emit = defineEmits(['submit']) // TS 写法 const emit = defineEmits<{ (e: 'submit', id: number): void }>() </script>
4. 依赖注入
- 直接使用
provide/inject:<script setup> import { provide } from 'vue' provide('key', 'value') </script>
5. 生命周期钩子
- 直接导入使用(如
onMounted):<script setup> import { onMounted } from 'vue' onMounted(() => console.log('组件挂载')) </script>
6. 动态组件与异步
- 动态组件:通过
:is绑定组件名或导入的组件对象:<script setup> import CompA from './CompA.vue' const current = shallowRef(CompA) </script> <template> <component :is="current" /> </template> - 异步组件:配合
defineAsyncComponent:<script setup> import { defineAsyncComponent } from 'vue' const AsyncComp = defineAsyncComponent(() => import('./Comp.vue')) </script>
7. 高级特性
- 暴露组件实例:通过
defineExpose暴露特定属性:<script setup> const a = 1 defineExpose({ a }) // 父组件通过 ref 访问 </script> - 属性透传:使用
useAttrs()访问非 props 的 attribute:<script setup> import { useAttrs } from 'vue' const attrs = useAttrs() </script>
8. 与选项式 API 对比
| 场景 | <script setup> 方案 | 选项式 API 方案 |
|---|---|---|
| 逻辑复用 | 组合式函数 | Mixins |
| 类型支持 | 完整的 TS 推导 | 有限支持 |
| 代码组织 | 按功能聚合 | 按选项分离 |
| 性能 | 编译优化更高效 | 需要运行时处理 |
9. 最佳实践
- 单一职责:将复杂逻辑拆分为组合式函数(如
useFetch())。 - 类型安全:优先使用 TypeScript 泛型(如
defineProps<{...}>())。 - 避免隐式依赖:显式导入工具函数而非依赖全局变量。