, ,

Vue 和 React 在父子组件通信上的核心区别

Vue 和 React 在父子组件通信上的核心区别在于数据流向的设计哲学:Vue 倾向于事件驱动(子组件主动抛…

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>
    </>
  )
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor