在 Vue 3 + JavaScript 环境中,definePropsdefineEmits<script setup> 语法糖中用于声明组件 props 和自定义事件的编译时宏。以下是详细用法说明和示例。

一、defineProps —— 声明父传子的数据

基本用法

<script setup>
// 基础写法:数组形式(不推荐,无类型校验)
const props = defineProps(['title', 'count'])

// 对象形式(推荐,可添加校验)
const props = defineProps({
  title: String,
  count: {
    type: Number,
    required: true,
    default: 0
  },
  isShow: {
    type: Boolean,
    default: false
  }
})
</script>

<template>
  <div>
    <h2>{{ title }}</h2>
    <p>Count: {{ count }}</p>
    <p v-if="isShow">显示内容</p>
  </div>
</template>

常用校验选项

选项 说明
type 数据类型(String/Number/Boolean/Array/Object/Function)
required 是否必传
default 默认值(对象/数组需用函数返回)
validator 自定义校验函数
age: {
  type: Number,
  validator: (value) => value >= 0 && value <= 150
}

二、defineEmits —— 声明子传父的事件

基本用法

<script setup>
const emit = defineEmits(['change', 'submit'])

const handleClick = () => {
  emit('change', '新值')
  emit('submit', { id: 1 })
}
</script>

<template>
  <button @click="handleClick">触发事件</button>
</template>

对象写法(支持校验)

const emit = defineEmits({
  change: (payload) => typeof payload === 'string',
  submit: null // 无校验
})

三、完整示例(父子组件通信)

子组件 Child.vue

<script setup>
const props = defineProps({
  msg: {
    type: String,
    default: 'Hello'
  }
})

const emit = defineEmits(['reply'])

const sendReply = () => {
  emit('reply', '来自子组件的消息')
}
</script>

<template>
  <div>
    <p>{{ msg }}</p>
    <button @click="sendReply">回复父组件</button>
  </div>
</template>

父组件 Parent.vue

<script setup>
import { ref } from 'vue'
import Child from './Child.vue'

const message = ref('父组件消息')

const handleReply = (val) => {
  console.log(val)
}
</script>

<template>
  <Child :msg="message" @reply="handleReply" />
</template>

四、注意事项(非常重要)

  1. 只能在 <script setup> 中使用
  2. 无需导入(编译器自动处理)
  3. props 是只读的(不能直接修改)
  4. 事件名推荐使用 kebab-case
  5. 不支持 TypeScript 时,对象写法更灵活

五、与 options API 对比

特性 defineProps / defineEmits props / emits 选项
语法 编译宏 选项式
类型推断 一般 较弱
代码简洁度 ✅ 更高 ❌ 较冗余
是否推荐 ✅ Vue 3 首选 ⚠️ 兼容写法

如果你需要 TypeScript 版本默认值合并技巧与 v-model 结合使用,可以继续问我 👍

更多推荐