
概述
在 Vue 中,父组件可以通过 props 向子组件传递数据。这是组件间通信的基础方式之一,实现了父子组件之间的数据传递。
核心概念
Props 的作用
- 允许父组件向子组件传递数据
- 实现组件之间的数据共享
- 建立父子组件之间的通信桥梁
静态绑定 Props
当传递的数据是固定不变的时,可以通过静态绑定的方式传递 props。
语法格式:
<子组件标签名 自定义属性A="数据" 自定义属性B="数据" />
特点:
- 属性值默认为字符串类型
- 数据在模板编译时确定,不会动态变化
代码实现
1. 子组件(Count.vue)
<template>
<div>
初始值为:{{ num }}
</div>
</template>
<script setup>
const props = defineProps({
num: String
})
</script>
代码解析:
| 代码行 | 说明 |
|---|---|
| 第 3 行 | 使用 Mustache 语法输出 num 属性值 |
| 第 7-10 行 | 使用 defineProps 声明接收的 props |
| 第 9 行 | 声明 num 属性,类型为 String |
关键点:
defineProps是 Vue 3<script setup>中的编译宏- 子组件必须声明 props 才能接收父组件传递的数据
- 如果子组件未声明 props,传递的数据会被忽略
2. 父组件(Props.vue)
<template>
<div>
<Count num="1" />
</div>
</template>
<script setup>
import Count from './Count.vue'
</script>
代码解析:
| 代码行 | 说明 |
|---|---|
| 第 3 行 | 引用子组件并传递静态数据 |
| 第 8 行 | 导入子组件 Count |
关键点:
- 使用组件标签形式引用子组件
- 通过属性方式传递数据
- 属性名必须与子组件声明的 props 名称一致
3. 入口文件(main.js)
import { createApp } from 'vue'
import App from './components/2026523/Props.vue'
const app = createApp(App)
app.mount('#app')
说明:设置父组件 Props.vue 作为应用的根组件。
Props 的特性
单向数据流
- 数据从父组件流向子组件
- 子组件不能直接修改 props 的值
- 如果需要修改,应通过事件通知父组件
Props 类型验证
可以为 props 指定类型和其他验证规则:
<script setup>
const props = defineProps({
// 基础类型检查
num: Number,
// 多个可能的类型
title: [String, Number],
// 必填的字符串
name: {
type: String,
required: true
},
// 带默认值的数字
count: {
type: Number,
default: 0
},
// 带默认值的对象
config: {
type: Object,
default() {
return { size: 'medium' }
}
},
// 自定义验证函数
age: {
validator(value) {
return value >= 0 && value <= 120
}
}
})
</script>
Props 命名规范
- 在子组件中声明时使用 camelCase(小驼峰)
- 在模板中使用时推荐使用 kebab-case(短横线分隔)
<!-- 子组件中声明 -->
defineProps({
userName: String
})
<!-- 父组件中使用 -->
<ChildComponent user-name="张三" />
运行效果
页面显示:
初始值为:1
解析:
- 父组件通过
num="1"将字符串 "1" 传递给子组件 - 子组件通过
defineProps接收并使用该数据 - 通过模板插值输出结果
注意事项
- props 只读:子组件不应直接修改 props,这会导致数据流混乱
- 类型转换:静态绑定的 props 默认是字符串类型,如需其他类型需显式转换
- 未声明的 props:如果子组件未声明某个 props,传递的数据会被忽略
- 响应式:props 是响应式的,父组件数据变化会自动同步到子组件
组件间数据流图示
┌─────────────────────────────────────────────────────┐
│ 父组件 (Props.vue) │
│ <template> │
│ <Count num="1" /> ◄── 静态绑定 props │
│ </template> │
└───────────────────────┬─────────────────────────────┘
│
▼ 数据流向(单向)
│
┌───────────────────────┴─────────────────────────────┐
│ 子组件 (Count.vue) │
│ defineProps({ num: String }) ◄── 声明接收 │
│ {{ num }} ◄── 使用数据 │
└─────────────────────────────────────────────────────┘
扩展:动态绑定 Props
除了静态绑定,还可以使用 v-bind 进行动态绑定:
<template>
<div>
<!-- 动态绑定变量 -->
<Count :num="parentNum" />
<!-- 动态绑定表达式 -->
<Count :num="count + 1" />
<!-- 动态绑定布尔值 -->
<Count :disabled="isDisabled" />
</div>
</template>
<script setup>
import { ref } from 'vue'
import Count from './Count.vue'
const parentNum = ref(10)
const count = ref(5)
const isDisabled = ref(false)
</script>
区别:
- 静态绑定:
num="1"传递字符串 "1" - 动态绑定:
:num="1"传递数字 1
总结
| 要点 | 说明 |
|---|---|
| 传递方式 | 通过组件属性传递 |
| 声明方式 | 使用 defineProps |
| 数据流向 | 单向(父 → 子) |
| 默认类型 | 字符串 |
| 修改限制 | 子组件不能直接修改 |
通过 props 机制,Vue 实现了清晰的父子组件通信方式,保证了数据流的可预测性和组件的复用性。