在 Vue 中,父组件向子组件传递参数(props)时,可以传递 基本类型(值) 、对象 或 数组,但需要注意它们的 响应性 和 可变性。以下是详细说明:
1. 传递基本类型(值)
父组件传递 字符串、数字、布尔值 等基本类型时,子组件接收的是 单向数据流(子组件不能直接修改父组件的值)。
父组件
vue
复制
下载
<template>
<ChildComponent
:title="title"
:count="count"
:is-visible="isVisible"
/>
</template>
<script>
export default {
data() {
return {
title: "Hello Vue", // 字符串
count: 10, // 数字
isVisible: true // 布尔值
};
}
};
</script>
子组件
vue
复制
下载
<template>
<div>
<h1>{{ title }}</h1>
<p>Count: {{ count }}</p>
<p v-if="isVisible">This is visible</p>
</div>
</template>
<script>
export default {
props: {
title: String, // 字符串类型
count: Number, // 数字类型
isVisible: Boolean // 布尔类型
}
};
</script>
⚠️ 注意
-
子组件不能直接修改
props,否则会报错(Vue 遵循单向数据流)。 -
如果需要修改,可以在子组件内部用
data或computed接收:javascript
复制
下载
data() { return { localCount: this.count // 用 data 接收 }; }, computed: { doubleCount() { return this.count * 2; // 用 computed 计算 } }
2. 传递对象(Object)
如果父组件传递的是 对象,子组件接收的是 引用,修改对象的属性会影响父组件(因为 Vue 默认是 浅响应式)。
父组件
vue
复制
下载
<template>
<ChildComponent :user="user" />
</template>
<script>
export default {
data() {
return {
user: {
name: "Alice",
age: 25
}
};
}
};
</script>
子组件
vue
复制
下载
<template>
<div>
<p>Name: {{ user.name }}</p>
<p>Age: {{ user.age }}</p>
<button @click="changeName">Change Name</button>
</div>
</template>
<script>
export default {
props: {
user: Object // 对象类型
},
methods: {
changeName() {
this.user.name = "Bob"; // 直接修改对象的属性(会影响父组件!)
}
}
};
</script>
⚠️ 注意
-
直接修改
props对象的属性会影响父组件(因为对象是引用传递)。 -
如果不想影响父组件,可以 深拷贝:
javascript
复制
下载
data() { return { localUser: JSON.parse(JSON.stringify(this.user)) // 深拷贝 }; }
3. 传递数组(Array)
数组也是 引用类型,直接修改数组的元素会影响父组件。
父组件
vue
复制
下载
<template>
<ChildComponent :items="items" />
</template>
<script>
export default {
data() {
return {
items: ["Apple", "Banana", "Orange"]
};
}
};
</script>
子组件
vue
复制
下载
<template>
<div>
<ul>
<li v-for="item in items" :key="item">{{ item }}</li>
</ul>
<button @click="addItem">Add Item</button>
</div>
</template>
<script>
export default {
props: {
items: Array // 数组类型
},
methods: {
addItem() {
this.items.push("Grape"); // 直接修改数组(会影响父组件!)
}
}
};
</script>
⚠️ 注意
-
直接修改
props数组(如push、splice)会影响父组件。 -
如果不想影响父组件,可以 拷贝数组:
javascript
复制
下载
methods: { addItem() { const newItems = [...this.items, "Grape"]; // 创建新数组 this.$emit("update-items", newItems); // 通知父组件更新 } }
4. 动态响应式更新
如果希望父组件的 props 变化时子组件能响应,可以使用:
-
watch监听props变化:javascript
复制
下载
watch: { items(newVal) { console.log("Items changed:", newVal); } } -
computed计算新值:javascript
复制
下载
computed: { filteredItems() { return this.items.filter(item => item.startsWith("A")); } }
总结
| 类型 | 传递方式 | 是否影响父组件 | 推荐做法 |
|---|---|---|---|
| 基本类型(String、Number、Boolean) | 值传递 | ❌ 不影响 | 用 data 或 computed 接收 |
| 对象(Object) | 引用传递 | ✅ 会影响(修改属性时) | 深拷贝或 emit 通知父组件 |
| 数组(Array) | 引用传递 | ✅ 会影响(push、splice 时) | 创建新数组或 emit 通知父组件 |
最佳实践
- 避免直接修改
props,用data或computed接收。 - 对象/数组修改时,尽量用
$emit通知父组件更新,而不是直接修改。
这样能保证数据流清晰,避免意外的副作用! 🚀