defineProps
和 defineEmits
都是只能在 <script setup>
中使用的编译器宏。他们不需要导入,且会随着 <script setup>
的处理过程一同被编译掉。
defineProps
接收与 props
选项相同的值,defineEmits
接收与 emits
选项相同的值,它们具备完整的类型推断并且在 script setup 中是直接可用的。
defineProps
或 defineEmits
要么使用运行时声明,要么使用类型声明。同时使用两种声明方式会导致编译报错
1、defineProps的用法:适用于父组件向子组件传递属性
基于类型的声明方式:
const props = defineProps<{
result: number,
name: string
}>()
运行时声明方式:
const props = defineProps({
result: Number,
name: {
type: String,
default: 'XXX' // 设置默认值
}
})
设置带默认的声明方式:主要有两种方式:
一种使用运行声明直接设置默认值,如果有复杂数据,就用函数形式返回数据,见下图:
另外一种是:在 3.5 及以上版本中,当使用响应式 Props 解构时,可以自然地声明默认值。但在 3.4 及以下版本中,默认情况下并未启用响应式 Props 解构。为了用基于类型声明的方式声明 props 的默认值,需要使用 withDefaults
编译器宏:,见下图:
请注意,在使用 withDefaults
时,默认值为可变引用类型 (如数组或对象) 应该封装在函数中,以避免意外修改和外部副作用。这样可以确保每个组件实例都获得默认值的自己的副本。在使用默认值解构时,这不是必要的。
2、defineEmits的用法:适用于父组件向子组件传递方法
基于类型的声明方式:
const emits = defineEmits<{
(e: 'add', id: number): void
(e: 'reset', value: number): void
}>()
const btnAdd = () => {
emits('add',2)
}
const btnReset = () => {
emits("reset",0)
}
运行时声明方式:
const emits = defineEmits(['change','update'])
3、defineExpose:适用于子组件向父组件暴露方法和属性,父组件通过子组件示例进行调用
子组件:
// 定义Expose
const exposeStr = ref<string>("")
defineExpose({
exposeStr
})
父组件:
<!-- 传入Props和Emits -->
<Detail ref="detail"></Detail>
--------------------------------------------------------------------
// 必须跟组件ref保持一致
const detail = ref()
setTimeout (() => {
detail.value.exposeStr = "exposeStr"
},1000)