🧩 Props 是啥?一句话说清楚
Props(属性)是父组件向子组件传递数据的单向通道。
你可以把它想象成:爸爸(父组件)给孩子(子组件)塞零花钱(数据),但孩子不能反过来改爸爸钱包里的钱(单向数据流)。这是 Vue 的"家规"!
✨ 基本用法:三步走,轻松上手
第一步:子组件声明接收哪些 props
在子组件中,使用 defineProps(组合式 API)或 props 选项(选项式 API)来声明它期望接收的数据。
html
<!-- ChildComponent.vue -->
<script setup>
// 组合式 API 写法(推荐)
const props = defineProps({
title: {
type: String,
required: true
},
count: {
type: Number,
default: 0
}
})
</script>
<template>
<div>
<h2>{{ title }}</h2>
<p>当前计数:{{ count }}</p>
</div>
</template>
💡 小贴士:
defineProps是 Vue 3 宏(macro),不需要 import!
第二步:父组件传递数据
在父组件中,像 HTML 属性一样给子组件"赋值"。
vue
<!-- ParentComponent.vue -->
<template>
<ChildComponent title="欢迎来到 Vue 世界!" :count="userScore" />
</template>
<script setup>
import ChildComponent from './ChildComponent.vue'
const userScore = 99
</script>
注意:title 是字符串字面量,直接写;而 count 是变量,要用 :(即 v-bind)绑定。
第三步:跑起来!看看效果
页面会显示:
欢迎来到 Vue 世界!
当前计数:99
搞定!是不是比点外卖还简单?
⚠️ 注意事项:这些坑我替你踩过了
1. 不要直接修改 props!
Vue 严格遵守单向数据流。如果你在子组件里尝试:
js
// ❌ 千万别这么干!
props.count++ // 控制台会警告你!
2. 类型校验很重要
虽然可以只写 defineProps(['title', 'count']),但强烈建议加上类型和默认值。这样:
- 防止传错类型(比如把数字当字符串传)
- 团队协作时别人一看就知道要传什么
- 减少 bug,提升代码健壮性
3. 对象/数组的默认值要用函数返回
因为对象和数组是引用类型,如果直接写 default: [],所有组件实例会共享同一个数组!
js
// ✅ 正确写法
items: {
type: Array,
default: () => []
}
4. 命名规范:camelCase vs kebab-case
在 JS 中用驼峰(myProp),在模板中用短横线(my-prop):
vue
<!-- 父组件模板 -->
<ChildComponent my-prop="hello" />
<!-- 子组件中 -->
defineProps({ myProp: String })
Vue 会自动帮你转换,但别搞混!
🎯 使用场景:什么时候该用 Props?
| 场景 | 是否适合用 Props |
|---|---|
| 父组件控制子组件显示内容(如标题、列表数据) | ✅ 非常适合 |
| 子组件需要配置(如按钮大小、主题色) | ✅ 用 props 传配置项 |
| 多个层级嵌套传递数据(祖传 props) | ⚠️ 可以,但超过 3 层建议用 provide/inject 或状态管理 |
| 子组件想改父组件的数据 | ❌ 用 emit + 父组件响应 |
🛠️ 实战示例:一个可配置的卡片组件
html
<!-- Card.vue -->
<script setup>
const props = defineProps({
title: { type: String, required: true },
content: { type: String, default: '' },
theme: {
type: String,
validator: (value) => ['light', 'dark'].includes(value),
default: 'light'
}
})
</script>
<template>
<div :class="`card card--${theme}`">
<h3>{{ title }}</h3>
<p>{{ content }}</p>
</div>
</template>
<style scoped>
.card--dark { background: #333; color: white; }
.card--light { background: #f5f5f5; }
</style>
父组件使用:
vue
<Card
title="今日任务"
content="学会 Props!"
theme="dark"
/>
看,一个灵活又安全的组件就诞生了!
✅ 总结:Props 的黄金法则
- 单向流动:父传子,子不能改。
- 明确声明:类型、默认值、是否必填,一个都不能少。
- 命名规范:JS 驼峰,模板短横线。
- 复杂数据用函数默认值:避免引用共享。