React18与Vue3组件通信对比学习(详细!建议收藏!!🚀🚀)

经过Vue3的洗礼,最近初始React18,还是觉得有必要对比一下两者进行通信的方式。 主要以 '父子通信','兄弟通信','跨域通信'进行展开

文章有点长,可以收藏起来,慢慢看~~ 但是不要让这篇文章吃灰·哦·

01| 父子组件通信

React18

1.父传子

  • 1.父传递数据 子组件标签上添加属性
  • 2.子组件接收数据 props 对象接收,包含父组件传递过来的所有属性
react 复制代码
function App() {
    return (
        <div>
            <Son1 name="李四" age={20} />
        </div>
    );
}
function Son1(props) {
    return (
        <div>
            <h2>姓名:{props.name}</h2>
            <h2>年龄:{props.age}</h2>
            <h2>内容:{props.children}</h2>
        </div>
    );
}

这里props.children,因为页面有显示props从父组件传递的内容,就为空

但是props.children 是一个很重要react里面重要概念。这里插入简单讲一下

props.children 允许你在组件中嵌套和传递子组件的内容。children 是一个特殊的 prop,它包含了组件标签内的所有子节点,无论是文本、元素还是其他组件。

当你在父组件中使用子组件时,如果没有显式传递某些内容,props.children 会自动接收子组件标签内的内容。

react 复制代码
function Parent() {
    return (
        <Child>
            <h1>第一个子节点</h1>
            <h2>第二个子节点</h2>
        </Child>
    );
}

function Child(props) {
    return (
        <div>
            <h2>我是子组件</h2>
            <div>
                {props.children ? props.children : <p>没有传递内容</p>}
            </div>
        </div>
    );
}

2.子传父

  • 1.父组件定义函数,子组件调用函数
  • 2.子组件传递函数给父组件
  • 3.父组件调用函数
react 复制代码
import React, { useState } from 'react';
function Parent() {
    const [msg, setMsg] = useState('');

    const getMsg = (msg) => {
        setMsg(msg);
    };
    
    return (
        <div>
            <h2>父组件状态:{msg}</h2>
            <Son1 getMsg={getMsg} />
        </div>
    );
}

function Son1({ getMsg }) {
    const sonMsg = '我是Son1子组件';
    return <button onClick={() => getMsg(sonMsg)}>点击传递消息</button>;
}

Vue3

1. 父传子

在 Vue 3 中,父组件通过 props 向子组件传递数据,子组件通过 defineProps 来声明接收的 props

vue 复制代码
<template>
  <!-- 使用'v-bind:name'将父组件中的parentName变量的值动态绑定到子组件的 `name` 属性上-->
  <Son :name="parentName" :age="parentAge" />
</template>

<script setup>
import { ref } from 'vue';
import Son from './Son.vue';

const parentName = ref('李四');
const parentAge = ref(20);
</script>
vue 复制代码
<!-- Son.vue -->
<template>
  <div>
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>
  </div>
</template>

<script setup>
// 子组件 defineProps 进行接收
defineProps({
  name: String,
  age: Number
});
</script>

2. 子传父

在 Vue 3 中,子组件通过 $emit 向父组件发送事件,父组件通过 v-on 监听该事件。

vue 复制代码
<!-- Parent.vue -->
<template>
  <!-- @ v-on 简写,使用 v-on 监听子组件的 sendMessage 事件 -->
  <Son @sendMessage="receiveMessage" />
  <p>{{ message }}</p>
</template>

<script setup>
import { ref } from 'vue';
import Son from './Son.vue';

const message = ref('');

function receiveMessage(msg) {
  message.value = msg;
}
</script>
vue 复制代码
<!-- Son.vue -->
<template>
  <button @click="sendMessage">点击传递消息</button>
</template>

<script setup>
const emit = defineEmits();

function sendMessage() {
     // 触发 'sendMessage' 事件,并传递消息作为参数
      emit('sendMessage', '我是Son组件');
}
</script>

上面defineEmits() 不用声明事件,可以传递任何事件,但同时也失去了对事件的类型检查和编译时验证。多项目中,未知事件传递带来风险。下面采用对象和数组两种方式简单说明,defineEmits()可以进行的检查和编译

数组形式示例

xml 复制代码
<template>
  <button @click="sendMessage">发送消息</button>
  <button @click="updateData">更新数据</button>
  <button @click="closeModal">关闭模态框</button>
</template>

<script setup>
// 明确声明可以发射的事件
const emit = defineEmits(['sendMessage', 'updateData', 'closeModal']);

function sendMessage() {
  emit('sendMessage', '我是Son组件');
}

function updateData() {
  emit('updateData', 123, { key: 'value' });
}

function closeModal() {
  emit('closeModal');
}
</script>

对象形式示例(TypeScript)

vue 复制代码
<script setup lang="ts">
interface Emit {
  (e: 'sendMessage', message: string): void;
  (e: 'updateData', id: number, data: object): void;
  (e: 'closeModal'): void;
}

// 明确声明可以发射的事件,并提供类型检查
const emit = defineEmits<Emit>();

</script>

02| 兄弟组件通信

React

兄弟组件的通信通过将共享的状态提升 到父组件来实现。父组件将该状态和修改状态的函数通过 props 传递给子组件。

react 复制代码
import React, { useState } from 'react';
function Parent() {
    const [msg, setMsg] = useState('');

    const getMsg = (msg) => {
        setMsg(msg);
    };

    return (
        <div>
            <h2>父组件状态:{msg}</h2>
            <Son1 getMsg={getMsg} />
            <Son2 msg={msg} />
        </div>
    );
}

function Son1({ getMsg }) {
    const sonMsg = '我是Son1子组件';
    return <button onClick={() => getMsg(sonMsg)}>传递消息</button>;
}

function Son2({ msg }) {
    return <h2>兄弟组件接收到的消息:{msg}</h2>;
}

Vue

在 Vue 3 中,兄弟组件的通信也通过将共享的状态提升到父组件来实现。父组件通过 props 向子组件传递数据,子组件通过 emit 向父组件传递事件。

vue 复制代码
<!-- Parent.vue -->
<template>
  <Son1 @sendMessage="receiveMessage" />
  <Son2 :msg="message" />
</template>

<script setup>
import { ref } from 'vue';
import Son1 from './Son1.vue';
import Son2 from './Son2.vue';

const message = ref('');

function receiveMessage(msg) {
  message.value = msg;
}
</script>
xml 复制代码
<!-- Son1.vue -->
<template>
  <button @click="sendMessage">传递消息</button>
</template>

<script setup>
const emit = defineEmits();

function sendMessage() {
  emit('sendMessage', '我是Son1子组件');
}
</script>
xml 复制代码
<!-- Son2.vue -->
<template>
  <h2>兄弟组件接收到的消息:{{ msg }}</h2>
</template>

<script setup>
defineProps({
  msg: String
});
</script>

03| 跨层组件通信:使用 context VS provide 实现

跨层通信由父App组件传给A里面的B组件

React

在 React 中,跨层组件通信可以通过 Context API 来实现。Context 允许你在组件树中传递数据,而不必手动通过每一层的 props。这种机制对于需要跨越多层嵌套的组件来说非常有用。

  • 1.createContext 创建 context 对象,上下文ctx 对象将包含你希望在组件树中共享的数据。
  • 2.Provider 提供器,包裹需要跨层通信的组件。将数据通过 value 属性传递给 Provider,任何位于 Provider 内部的组件都可以访问到这些数据。
  • 3.useContext 钩子来访问上下文中的数据。useContext 接受一个上下文对象(就是通过 createContext 创建的那个对象)作为参数,并返回该上下文的当前值。
js 复制代码
import React, { createContext, useContext } from 'react';

// 1. 创建 context 对象
const MsgContext = createContext();
function ContextApp() {
    const msg = 'this is app';

    return (
        <>
            {/* 2. 使用 Provider 包裹组件并提供数据 */}
            <MsgContext.Provider value={msg}>
                <div>
                    <h2>我是 App 组件</h2>
                    <A />
                </div>
            </MsgContext.Provider>
        </>
    );
}
function A() {
    const sonMsg = '我是 son1 子组件';
    return (
        <>
            {sonMsg}
            <B />
        </>
    );
}
function B() {
    // 3. 使用 useContext 钩子接收数据
    const msg = useContext(MsgContext);
    return (
        <>
            <div>this is B,{msg}</div>
        </>
    );
}
export default ContextApp;

Vue 3

在 Vue 3 中,跨层组件通信可以通过 provideinject API 来实现。provide 用于提供数据,而 inject 用于在后代组件中获取这些数据。这是 Vue 中实现跨层组件通信的标准方法。

js 复制代码
<!-- Parent.vue -->
<template>
  <div>
    <h2>我是 App 组件</h2>
    <A />
  </div>
</template>

<script setup>
import { provide } from 'vue';
import A from './A.vue';

const msg = 'this is app';

// 1. 使用 provide 提供数据
provide('msg', msg);
</script>
js 复制代码
<!-- A.vue -->
<template>
  <div>
    我是 son1 子组件
    <B />
  </div>
</template>

<script setup>
import B from './B.vue';
</script>
js 复制代码
<!-- B.vue -->
<template>
  <div>
    this is B,{{ msg }}
  </div>
</template>

<script setup>
import { inject } from 'vue';

// 2. 使用 inject 获取数据
const msg = inject('msg');
</script>

对比:React 与 Vue 的跨层通信

特性 React Vue 3
跨层通信方式 contextuseContext provideinject
数据传递方向 Provider 向下传递数据, Consumer 获取数据 provide 在父组件提供数据, inject 在后代组件获取数据
适用场景 适用于中等规模应用,尤其是需要共享全局状态时 适用于需要跨越多个层级传递数据的场景

总结

React18和Vue3 机制都是为了简化,Vue3哲学注重业务开发,所以通过很多对应的语法。比如,props接收参数,'v-bind'等。React18 适合大型项目,在管理项目和JavaScript运用上面都有深入。 就以跨层组件通信来说,通过 Context (React)或 provide/inject(Vue 3) API,开发者可以更加方便地进行跨层组件通信,尤其是当数据需要在深层嵌套的组件间共享时,能极大简化组件的结构和数据流动。

**我相信看到这里的小伙伴中肯定会出现绝世高手~**🚀 🚀

希望这篇文章对大家有帮助,欢迎评论区探讨学习,学会的话也还请给本文一个点赞支持哦~

相关推荐
自然 醒22 分钟前
如何实现el-select多选下拉框中嵌套复选框并加校验不为空功能呢?
前端·javascript·vue.js
成功之路必定艰辛1 小时前
【Mars3D项目实战开发】vue3+vite搭建配置项3维地球
前端·vue3·mars3d
爱学习的小羊啊1 小时前
【前端】Vue3 父传子 Dialog 显示问题:解决方案与最佳实践
前端
余生H1 小时前
前端Python应用指南(八)WebSocket与实时应用:用Flask和Django实现聊天系统
前端·python·websocket·实时通讯
国服第二切图仔1 小时前
鸿蒙Next自定义相机开发时,如何解决相机在全屏预览的时候,画面会有变形和拉伸?
前端·javascript·harmonyos
it非鱼2 小时前
超详细!uni-app Android本地打包傻瓜式教程
前端
坐镇指挥2 小时前
vue组件设计
前端·javascript·vue.js
Mr。轩。2 小时前
【Vue】分享一个快速入门的前端框架以及如何搭建
前端·vue.js·前端框架
yzzzz2 小时前
JS 的蝴蝶效应 —— 事件流
前端·javascript·面试
计算机学姐2 小时前
基于Python的社交音乐分享平台
开发语言·vue.js·python·mysql·django·flask·pip