在 Vue(尤其是 Vue 2 / Options API)里,props 和 data 都是组件中的数据来源,但职责完全不同。可以理解为:
- props:外部传进来的数据(输入)
- data:组件自己维护的数据(内部状态)
| 对比项 | props | data |
|---|---|---|
| 数据来源 | 父组件传入 | 组件自己定义 |
| 所有权 | 父组件 | 当前组件 |
| 是否可直接修改 | 不建议(只读) | 可以 |
| 用途 | 输入参数 | 内部状态 |
| 更新方向 | 父 → 子 | 本组件内部 |
一、props
1. props:父组件传给子组件的数据
props 是组件之间通信 的方式,通常是 父 → 子。
父组件
<template>
<UserCard :name="userName" />
</template>
<script>
export default {
data() {
return {
userName: "Tom"
}
}
}
</script>
子组件
<script>
export default {
props: {
name: String
}
}
</script>
<template>
<div>{{ name }}</div>
</template>
这里:
userName在父组件里- 通过
props传给子组件 - 子组件通过
name接收
特点
① 由父组件控制
父组件改了,子组件自动更新。
this.userName = "Jerry"
子组件里的 name 也会变。
② 单向数据流(one-way data flow)
子组件不要直接修改 props。
错误写法:
this.name = "abc"
Vue 会警告:
Avoid mutating a prop directly
因为:
- 数据所有权在父组件
- 父组件一刷新,值会覆盖回来
如果要改,一般复制一份到 data:
props: ['name'],
data() {
return {
localName: this.name
}
}
然后修改:
this.localName = "new value"
二、data:组件自己的内部状态
data 是组件自己管理的数据。
例如:
<script>
export default {
data() {
return {
count: 0
}
}
}
</script>
<template>
<button @click="count++">
{{ count }}
</button>
</template>
这里:
count不来自父组件- 是组件内部状态
- 组件自己维护
特点
① 可修改
this.count++
没问题。
② 每个组件实例独立
Vue 要求 data 必须是函数:
data() {
return {
count: 0
}
}
不能:
data: {
count: 0
}
因为多个组件实例会共享同一个对象,导致数据串了。