vue3 setup的平级函数(宏函数)
在 Vue3 的 <script setup>
语法中,编译时宏函数(也称 “平级函数”)是一类特殊 API,它们无需导入即可直接使用,仅在 <script setup>
作用域内生效,用于处理组件核心逻辑。
一、核心宏函数(按功能分类)
1. 组件属性与事件处理
defineProps
-
作用:声明组件接收的 props,替代选项式 API 中的
props
选项。 -
语法:
// 基础形式(数组) const props = defineProps(['title', 'visible'])// 完整形式(对象,支持类型验证) const props = defineProps({title: {type: String,required: true,default: '默认标题'},visible: {type: Boolean,default: false} })// TypeScript 形式 const props = defineProps<{id: numbername?: string }>()
-
特性:返回的
props
对象是响应式的,可直接在模板中使用,不可手动修改。
defineEmits
-
作用:声明组件可触发的自定义事件,替代选项式 API 中的
emits
选项。 -
语法:
// 基础形式(数组) const emit = defineEmits(['change', 'delete'])// 完整形式(对象,支持参数验证) const emit = defineEmits({change: (value: string) => value.length > 0, // 验证参数有效性delete: (id: number) => id > 0 })// 触发事件 emit('change', 'new value')
-
特性:返回的
emit
函数用于触发事件,参数验证失败时会在开发环境报警告。
defineModel
(Vue 3.4+)
-
作用:简化
v-model
双向绑定逻辑,自动处理modelValue
props 和update:modelValue
事件。 -
语法:
// 基础用法(对应 v-model) const modelValue = defineModel()// 带配置用法(多 v-model 场景) const count = defineModel({type: Number,default: 0,event: 'update:count' // 自定义事件名 })// 修改值(自动触发更新事件) const increment = () => {count.value++ }
-
父组件使用:
<MyComponent v-model="parentValue" v-model:count="parentCount" />
2. 组件暴露与访问
defineExpose
-
作用:显式暴露组件内部属性 / 方法,供父组件通过模板引用访问(
<script setup>
中默认私有)。 -
语法:
import { ref } from 'vue'const internalCount = ref(0) const reset = () => { internalCount.value = 0 }// 暴露给父组件的成员 defineExpose({internalCount,reset })
-
父组件访问:
const childRef = ref(null) // 调用子组件暴露的方法 childRef.value?.reset()
useSlots
-
作用:访问父组件传递的插槽内容,替代选项式 API 中的
this.$slots
。 -
语法:
import { useSlots } from 'vue'const slots = useSlots() // 检查默认插槽是否存在 const hasDefaultSlot = !!slots.default // 访问具名插槽 const headerSlot = slots.header?.()
useAttrs
-
作用:访问父组件传递的非 props 属性(如
class
、style
、自定义属性),替代选项式 API 中的this.$attrs
。 -
语法:
import { useAttrs } from 'vue'const attrs = useAttrs() // 访问属性(响应式对象) console.log(attrs.id) // 父组件传递的 id 属性 console.log(attrs.class) // 父组件传递的 class
3. 配置与辅助
withDefaults
-
作用:为 TypeScript 类型的 props 提供默认值,解决
defineProps<Type>()
无法直接设置默认值的问题。 -
语法:
interface Props {size?: numberlabels?: string[] }const props = withDefaults(defineProps<Props>(), {size: 16,// 复杂类型默认值需用函数返回(避免共享引用)labels: () => ['default'] })
defineOptions
(Vue 3.3+)
-
作用:在
<script setup>
中直接声明组件选项(如name
、inheritAttrs
),无需额外的<script>
块。 -
语法:
defineOptions({name: 'CustomButton', // 组件名称(用于调试、递归组件)inheritAttrs: false, // 禁止非props属性继承到根元素directives: {// 局部注册指令focus: { mounted: (el) => el.focus() }} })
二、宏函数的共同特性
- 编译时处理:宏函数由 Vue 编译器在编译阶段解析,不会出现在运行时代码中。
- 作用域限制:仅能在
<script setup>
中使用,普通<script>
或外部 JS 文件中无效。 - 无需导入:由编译器内置,直接调用即可(
useSlots
和useAttrs
除外,需从vue
导入)。 - 类型友好:与 TypeScript 结合时提供完整类型推断,支持 IDE 语法提示。
三、使用场景总结
宏函数 | 核心场景 | 版本要求 |
---|---|---|
defineProps | 声明组件输入属性 | Vue 3.2+ |
defineEmits | 声明组件输出事件 | Vue 3.2+ |
defineModel | 简化双向绑定(v-model) | Vue 3.4+ |
defineExpose | 暴露组件内部成员给父组件 | Vue 3.2+ |
useSlots | 访问插槽内容 | Vue 3.2+ |
useAttrs | 处理非 props 属性(class、style 等) | Vue 3.2+ |
withDefaults | TypeScript 环境下设置 props 默认值 | Vue 3.2+ |
defineOptions | 声明组件元信息(name、inheritAttrs 等) | Vue 3.3+ |
这些宏函数是 <script setup>
语法的核心,通过它们可以高效实现组件的属性传递、事件通信、内部暴露等核心功能,同时保持代码的简洁性和可维护性。