Vue 和 React 在父子组件通信上的核心区别在于数据流向的设计哲学:Vue 倾向于事件驱动(子组件主动抛出事件),而 React 倾向于回调函数驱动(父组件把函数传给子组件去调用)。
1. 父组件向子组件传递数据(父 → 子)
核心区别:两者都使用 props,但 Vue 有严格的单向数据流限制,React 则更加宽松。
Vue 写法:
<!-- 父组件 -->
<ChildComponent :message="msg" />
<!-- 子组件 -->
<script setup>
const props = defineProps(['message'])
// 注意:Vue 中绝对不能直接修改 props,否则控制台会报警告
// props.message = 'new'
</script>
React 写法:
// 父组件
<ChildComponent message={msg} />
// 子组件
function ChildComponent({ message }) {
// React 中虽然也不建议直接修改 props,但不会像 Vue 那样强制拦截
return <p>{message}</p>
}
2. 子组件向父组件传递消息/响应事件(子 → 父)
核心区别:
- Vue:子组件通过
emit主动触发一个自定义事件,父组件在标签上通过@事件名监听。 - React:父组件通过 props 将一个回调函数传给子组件,子组件在合适的时机调用这个函数。
Vue 写法:
<!-- 子组件 Child.vue -->
<script setup>
const emit = defineEmits(['send-msg'])
const handleClick = () => {
emit('send-msg', '来自Vue子组件的消息') // 主动抛出事件
}
</script>
<template>
<button @click="handleClick">发送消息</button>
</template>
<!-- 父组件 Parent.vue -->
<template>
<!-- 监听子组件抛出的 send-msg 事件 -->
<Child @send-msg="handleReceive" />
</template>
React 写法:
// 子组件 Child.jsx
function Child({ onSendMsg }) {
const handleClick = () => {
onSendMsg('来自React子组件的消息') // 调用父组件传下来的函数
}
return <button onClick={handleClick}>发送消息</button>
}
// 父组件 Parent.jsx
function Parent() {
const handleReceive = (data) => {
console.log(data)
}
// 把回调函数作为 prop 传给子组件
return <Child onSendMsg={handleReceive} />
}
3. 父组件直接调用子组件的方法(父 → 子 调用)
核心区别:
- Vue:使用
ref获取子组件实例,配合defineExpose暴露方法。 - React:使用
useRef获取子组件实例,配合forwardRef和useImperativeHandle暴露方法。
Vue 写法:
<!-- 子组件 Child.vue -->
<script setup>
const reset = () => console.log('Vue 表单重置')
// 必须通过 defineExpose 显式暴露,父组件才能访问
defineExpose({ reset })
</script>
<!-- 父组件 Parent.vue -->
<script setup>
import { ref } from 'vue'
const childRef = ref(null)
const triggerReset = () => childRef.value.reset() // 直接调用
</script>
<template>
<Child ref="childRef" />
<button @click="triggerReset">重置</button>
</template>
React 写法:
// 子组件 Child.jsx
import { forwardRef, useImperativeHandle } from 'react'
// 必须用 forwardRef 包裹
const Child = forwardRef((props, ref) => {
const reset = () => console.log('React 表单重置')
// 通过 useImperativeHandle 将方法绑定到 ref 上
useImperativeHandle(ref, () => ({ reset }))
return <div>Child</div>
})
// 父组件 Parent.jsx
import { useRef } from 'react'
function Parent() {
const childRef = useRef()
const triggerReset = () => childRef.current.reset() // 通过 .current 调用
return (
<>
<Child ref={childRef} />
<button onClick={triggerReset}>重置</button>
</>
)
}




