Props 和 Events(父子组件通信)
Props:父组件向子组件传递数据使用
props
。子组件通过声明props
来接收来自父组件的数据。<!-- 父组件 --> <template> <ChildComponent :message="parentMessage" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, data() { return { parentMessage: 'Hello from parent' }; } }; </script>
<!-- 子组件 --> <template> <div>{{ message }}</div> </template> <script> export default { props: ['message'] }; </script>
Events:子组件向父组件发送消息或数据可以使用
$emit
方法触发自定义事件。<!-- 子组件 --> <template> <button @click="sendMessage">Send Message</button> </template> <script> export default { methods: { sendMessage() { this.$emit('childEvent', 'Hello from child'); } } }; </script>
<!-- 父组件 --> <template> <ChildComponent @childEvent="handleChildEvent" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, methods: { handleChildEvent(message) { console.log(message); } } }; </script>
ChildComponent.vue
,它需要向父组件发送两个参数:message
和 status
。
<template>
<button @click="sendDataToParent">Send Data to Parent</button>
</template>
<script>
export default {
data() {
return {
message: 'Hello from Child',
status: 'success'
};
},
methods: {
sendDataToParent() {
// 使用 $emit 触发自定义事件,并传递多个参数
this.$emit('dataFromChild', this.message, this.status);
}
}
};
</script>
在这个例子中,当按钮被点击时,会调用 sendDataToChild
方法,该方法使用 $emit
来触发名为 dataFromChild
的自定义事件,并传递了两个参数:this.message
和 this.status
。
父组件代码
接下来,在父组件中引入 ChildComponent
并监听 dataFromChild
事件。
<template>
<div>
<!-- 监听来自子组件的自定义事件 -->
<ChildComponent @dataFromChild="handleDataFromChild" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
methods: {
handleDataFromChild(message, status) {
console.log('Message:', message); // 输出: Hello from Child
console.log('Status:', status); // 输出: success
// 在这里处理接收到的数据
}
}
};
</script>
在这个父组件的例子中,@dataFromChild="handleDataFromChild"
表示监听子组件发出的 dataFromChild
事件,并在事件发生时调用 handleDataFromChild
方法。此方法接收子组件传递过来的参数(在这个例子中是 message
和 status
),然后可以根据业务需求对这些数据进行处理。
这种方法可以让你轻松地在子组件和父组件之间传递任意数量的参数。只需要确保在 $emit
调用时传递正确的参数,并在父组件的方法中正确接收它们即可
父组件在监听子组件事件的同时,还需要传递自己的参数
- 子组件通过
$emit
触发事件,传递自己的数据(如:childData
)。 - 父组件监听该事件,同时还想传入自己的参数(如:
parentId
,category
等)。 - 最终父组件的处理函数需要 同时拿到子组件的数据 + 父组件自己的参数。
方法一:使用内联箭头函数(推荐)
这是最清晰、最常用的方式。
<!-- 父组件 ParentComponent.vue -->
<template>
<div>
<!-- 使用箭头函数包装,同时传入父组件参数 -->
<ChildComponent
@dataFromChild="(childData) => handleData(childData, parentId, 'user')"
/>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
data() {
return {
parentId: 1001,
};
},
methods: {
handleData(childData, parentId, type) {
console.log('来自子组件的数据:', childData);
console.log('父组件自己的参数:', parentId, type);
// 处理逻辑...
}
}
};
</script>
✅ 优点:语义清晰,支持传任意多个父参数。
方法二:使用包装函数(命名函数)
如果你不想用内联箭头函数,也可以封装一个中间函数。
<template>
<ChildComponent @dataFromChild="wrapperHandler" />
</template>
<script>
export default {
data() {
return {
parentId: 1001,
};
},
methods: {
wrapperHandler(childData) {
// 在这里调用真正的处理函数,并传入父组件参数
this.handleData(childData, this.parentId, 'admin');
},
handleData(childData, parentId, role) {
console.log(childData, parentId, role);
}
}
};
</script>
✅ 优点:逻辑分离,适合复杂逻辑。
✅ 方法三:使用 $event
隐式变量(传统方式)
Vue 会把 $emit
的第一个参数自动传给监听函数,可以用 $event
接收。
<template>
<ChildComponent @dataFromChild="handleData($event, parentId, 'guest')" />
</template>
<script>
export default {
data() {
return {
parentId: 1001,
};
},
methods: {
handleData(childData, parentId, userType) {
console.log(childData, parentId, userType);
}
}
};
</script>
⚠️ 注意:
$event
是子组件$emit
传递的第一个参数。如果有多个参数,$event
只是第一个。如果要传递多个,可以把参数包装成一个对象.
<!-- ChildComponent.vue -->
<template>
<button @click="sendData">Send Data</button>
</template>
<script>
export default {
methods: {
sendData() {
this.$emit('dataFromChild', {
name: 'Alice',
age: 25
});
}
}
};
</script>
✅ 总结
方法 | 说明 | 推荐度 |
---|---|---|
内联箭头函数 (data) => handler(data, param) |
最灵活,推荐 | ⭐⭐⭐⭐⭐ |
包装函数 | 逻辑清晰,适合复杂处理 | ⭐⭐⭐⭐☆ |
$event + 参数 |
传统写法,稍显隐晦 | ⭐⭐⭐☆☆ |