非常好 👍
下面我来系统讲解 Vue 3 中 Props 的声明与使用方法,从基础到进阶全面讲透。
内容适合所有使用 Vue 3(Composition API / <script setup>
)的开发者。
📘 Vue 3 Props 声明与使用全指南
一、什么是 Props?
Props(属性) 是父组件向子组件传递数据的机制。
父组件传值 → 子组件通过 props
接收并使用。
<!-- 父组件 -->
<Child :title="msg" />
<!-- 子组件 -->
<script setup>
const props = defineProps(['title'])
</script>
<template>
<p>{{ title }}</p>
</template>
二、Props 的三种声明方式
✅ 1. 简单字符串数组(最基础)
<script setup>
const props = defineProps(['title', 'count'])
</script>
📌 适合快速开发,不支持类型、默认值、校验。
✅ 2. 对象语法(传统方式)
<script setup>
const props = defineProps({
title: {
type: String,
default: '默认标题'
},
count: {
type: Number,
required: true
},
isActive: Boolean // 简写形式
})
</script>
🧩 参数说明:
选项 | 作用 | 示例 |
---|---|---|
type | 指定类型 | String , Number , Boolean , Array , Object , Function |
required | 是否必传 | required: true |
default | 默认值 | default: 'Hello' |
validator | 自定义验证函数 | validator: v => ['A', 'B'].includes(v) |
✅ 3. 使用 TypeScript 接口定义(推荐现代写法)
<script setup lang="ts">
interface Props {
title: string
count?: number
isActive?: boolean
}
const props = defineProps<Props>()
</script>
🧠 优点:
- IDE 自动补全和类型检查;
- 更简洁;
- 更适合大型项目。
三、结合默认值:withDefaults
使用类型定义时不能直接设置 default
,此时可用 withDefaults()
:
<script setup lang="ts">
interface Props {
title?: string
count?: number
}
const props = withDefaults(defineProps<Props>(), {
title: '默认标题',
count: 0
})
</script>
✅ 相当于:
const props = defineProps({
title: { type: String, default: '默认标题' },
count: { type: Number, default: 0 }
})
四、在模板中使用 Props
模板中可以直接访问 props(不用加 props.
):
<template>
<h2>{{ title }}</h2>
<p>数量:{{ count }}</p>
</template>
五、Props 是只读的
⚠️ 不能修改 props 值!
props.count++ // ❌ 报错
如果要修改,可以复制成本地响应式变量:
import { ref } from 'vue'
const count = ref(props.count)
count.value++
或者通过事件通知父组件更新。
六、父组件传值示例
父组件(App.vue)
<template>
<Child :title="msg" :count="5" />
</template>
<script setup>
const msg = '来自父组件的标题'
</script>
子组件(Child.vue)
<script setup>
const props = defineProps({
title: String,
count: Number
})
</script>
<template>
<h3>{{ title }} - {{ count }}</h3>
</template>
七、结合 defineEmits
(父子通信)
子组件可以通过 emit
通知父组件更新:
<script setup>
const props = defineProps({ count: Number })
const emit = defineEmits(['update-count'])
const add = () => emit('update-count', props.count + 1)
</script>
父组件监听:
<Child :count="count" @update-count="count = $event" />
八、进阶:v-model 的 Props
在 Vue 3 中,v-model
本质是 modelValue
+ update:modelValue
。
子组件
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
const update = () => emit('update:modelValue', props.modelValue + 1)
</script>
<template>
<p>{{ modelValue }}</p>
<button @click="update">增加</button>
</template>
父组件
<Child v-model="count" />
这等价于:
<Child :modelValue="count" @update:modelValue="count = $event" />
九、Props 校验示例
你也可以为 props 设置自定义校验函数:
<script setup>
const props = defineProps({
level: {
type: Number,
validator: v => v >= 1 && v <= 5
}
})
</script>
🔟 Props 声明方式对比总结
声明方式 | 特点 | 是否支持默认值 | 是否支持类型检查 |
---|---|---|---|
数组写法 | 简洁、无验证 | ❌ | ❌ |
对象写法 | 支持验证、默认值 | ✅ | ✅(运行时) |
TypeScript 类型 | 最现代、推荐 | ✅(需 withDefaults) | ✅(编译时) |
✅ 推荐实践(现代 Vue3 项目写法)
<script setup lang="ts">
interface Props {
title?: string
count?: number
isActive?: boolean
}
const props = withDefaults(defineProps<Props>(), {
title: '默认标题',
count: 0,
isActive: true
})
</script>
<template>
<div>
<h2>{{ title }}</h2>
<p>{{ count }}</p>
</div>
</template>
发表回复