defineprops和defineemits是vue 3 中无需导入的编译器宏:前者声明props,支持运行时对象或ts类型声明(推荐withdefaults设默认值);后者声明自定义事件,推荐ts函数签名或元组语法,未声明事件将归入$attrs。
` 中使用 defineprops 和 defineemits">
在 Vue 3 的 <script setup></script> 语法中,defineProps 和 defineEmits 是编译器宏,无需导入,直接调用即可声明组件接收的 props 和可触发的事件。
defineProps:声明接收的属性
用于定义子组件从父组件接收的数据。支持两种写法,推荐根据项目是否使用 TypeScript 选择:
-
运行时声明(适合 JS 或基础 TS 项目):
传入一个对象,每个 key 对应 prop 名,值可指定type、required、default、validator等选项。
注意:数组/对象类型的default必须是函数返回值。 -
类型声明(TS 推荐):
直接传入接口或内联类型,如defineProps()。
此时不写运行时配置,类型信息会自动转为等效的运行时校验(开发模式下生效)。 - 若需设置默认值且用类型声明,搭配
withDefaults:withDefaults(defineProps(), { title: '默认标题' })
defineEmits:声明并触发自定义事件
用于明确子组件能向外抛出哪些事件,避免隐式 emit 导致调试困难。
-
数组写法(简单场景):
const emit = defineEmits(['update', 'delete']),之后调用emit('update', newValue)即可。 -
类型声明(TS 推荐,校验参数):
可用函数签名形式:defineEmits();
或 Vue 3.3+ 的简洁元组语法:defineEmits()。 - 不声明的事件(如
click)会被归入$attrs,可能意外透传到根元素——务必显式声明你主动emit的事件。
配合模板使用的注意事项
在 <template></template> 中可直接访问 props 的字段(如 {{ title }}),无需通过 props.title;但 script 中需通过解构或 props.xxx 访问。
- 父组件传非字符串值必须用
v-bind:(或简写:),例如<child :count="5" :list="[1,2]"></child>;传字符串字面量可省略绑定:<child title="hello"></child>。 - 子组件触发事件后,父组件用
@事件名监听,例如<child></child>。 - 如果组件需要被父组件调用方法或读取响应式数据,还需配合
defineExpose显式暴露。
常见错误提醒
以下写法会导致编译报错或行为异常:
- 同时使用运行时对象和类型泛型(如
defineProps({b:Number})); - 未在
defineEmits中声明却调用了emit('xxx')(TS 下报错,JS 下仅警告); - 给 prop 设置对象/数组默认值时没写成函数:
default: []❌,应写default: () => []✅。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










