一、Props 声明方式
| 声明方式 | 代码示例 | 特点 |
|---|---|---|
| 数组形式 | defineProps(['foo']) | 简单易用,仅声明 prop 名 |
| 对象形式 | defineProps({ foo: String }) | 可声明类型、默认值、是否必填等 |
| TypeScript 类型标注 | defineProps<{ foo?: string }>() | 适用于 TypeScript 项目,类型安全 |
二、Props 类型声明
defineProps({
propA: Number, // 基础类型
propB: [String, Number], // 多种类型
propC: { type: String, required: true }, // 必填项
propD: { type: [String, null], required: true }, // 可为 null 的必填项
propE: { type: Number, default: 100 }, // 带默认值
propF: { type: Object, default: () => ({ message: 'hello' }) }, // 对象默认值
propG: { validator: (value) => ['success', 'warning', 'danger'].includes(value) } // 自定义校验
})
三、响应式 Props 解构
1. 解构 Props
const { foo } = defineProps(['foo'])
2. 响应式特性
watchEffect(() => {
console.log(foo) // 在 3.5+ 中,当 foo 变化时重新执行
})
3. 默认值解构
const { foo = 'hello' } = defineProps<{ foo?: string }>()
四、Prop 传递方式
| 传递方式 | 示例 | 说明 |
|---|---|---|
| 静态值 | <MyComponent title="Hello" /> | 传递字符串常量 |
| 动态绑定 | <MyComponent :title="post.title" /> | 传递变量或表达式 |
| 对象绑定 | <MyComponent v-bind="post" /> | 一次性传递对象所有属性 |
五、Prop 类型传递示例
| 类型 | 静态示例 | 动态示例 |
|---|---|---|
| Number | <BlogPost :likes="42" /> | <BlogPost :likes="post.likes" /> |
| Boolean | <BlogPost is-published /> | <BlogPost :is-published="post.isPublished" /> |
| Array | <BlogPost :comment-ids="[234, 266, 273]" /> | <BlogPost :comment-ids="post.commentIds" /> |
| Object | <BlogPost :author="{ name: 'Veronica' }" /> | <BlogPost :author="post.author" /> |
六、Prop 校验规则
defineProps({
propA: Number,
propB: [String, Number],
propC: { type: String, required: true },
propD: { type: [String, null], required: true },
propE: { type: Number, default: 100 },
propF: { type: Object, default: () => ({ message: 'hello' }) },
propG: { validator: (value) => ['success', 'warning', 'danger'].includes(value) }
})
七、Prop 类型检查
| 类型 | 示例 | 类型检查方式 |
|---|---|---|
| String | String | typeof value === 'string' |
| Number | Number | typeof value === 'number' |
| Boolean | Boolean | typeof value === 'boolean' |
| Array | Array | Array.isArray(value) |
| Object | Object | typeof value === 'object' |
| Date | Date | value instanceof Date |
| Function | Function | typeof value === 'function' |
| 自定义类 | Person | value instanceof Person |
八、Boolean 类型转换规则
| 声明类型 | 示例 | 转换结果 |
|---|---|---|
[Boolean, Number] | <MyComponent disabled /> | true |
[Boolean, String] | <MyComponent disabled /> | true |
[Number, Boolean] | <MyComponent disabled /> | true |
[String, Boolean] | <MyComponent disabled /> | "" |
九、单向数据流原则
所有 props 都遵循单向绑定原则:props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。
不正确的做法:
props.foo = 'bar' // ❌ 警告!prop 是只读的!
正确做法:
// 1. 局部数据属性
const counter = ref(props.initialCounter)
// 2. 计算属性
const normalizedSize = computed(() => props.size.trim().toLowerCase())
十、响应式传递解构的 Props
const { foo } = defineProps(['foo'])
// 错误用法
watch(foo, /* ... */) // ❌ 传递的是一个值而不是响应式数据源
// 正确用法
watch(() => foo, /* ... */) // ✅ 通过 getter 包装
useComposable(() => foo) // ✅ 推荐做法
十一、总结图表
1. Props 声明方式对比图
┌──────────────┬───────────────┬────────────────────┐
│ 声明方式 │ 适用场景 │ 优点 │
├──────────────┼───────────────┼────────────────────┤
│ 数组形式 │ 简单声明 │ 简洁易用 │
│ 对象形式 │ 完整声明 │ 支持类型、默认值等 │
│ TS 类型标注 │ TS 项目 │ 类型安全 │
└──────────────┴───────────────┴────────────────────┘
2. Prop 类型检查机制
┌───────────────┐
│ 类型声明 │
├───────────────┤
│ 基础类型检查 │
│ 多类型支持 │
│ 默认值 │
│ 自定义校验 │
└───────────────┘
↓
┌──────────────────┐
│ 运行时校验 │
├──────────────────┤
│ typeof 检查 │
│ instanceof 检查 │
│ 自定义 validator│
└──────────────────┘
↓
┌────────────────────┐
│ 开发环境警告 │
└────────────────────┘
3. Prop 传递方式流程图
Prop 传递方式
│
├─ 静态值传递
│ └─ <MyComponent title="Hello" />
│
├─ 动态绑定
│ └─ <MyComponent :title="post.title" />
│
└─ 对象绑定
└─ <MyComponent v-bind="post" />
十二、核心知识点
-
组件间通信机制
-
Props 是父组件向子组件传递数据的主要方式
-
遵循单向数据流原则,避免子组件修改父组件状态
-
-
响应式系统
-
Vue 的响应系统基于属性访问跟踪状态
-
在 3.5+ 版本中,解构的 props 仍保持响应性
-
-
类型校验机制
-
可通过多种方式声明 props 类型
-
支持运行时校验和 TypeScript 编译时校验
-
自定义校验函数可实现复杂校验逻辑
-
18万+

被折叠的 条评论
为什么被折叠?



