vue3、react组件数据传值对比分析——父组件传递子组件,子组件传递父组件(一)

简介: vue3、react组件数据传值对比分析——父组件传递子组件,子组件传递父组件

⭐前言

大家好,我是yma16,本文分享关于vue、react组件数据传值对比分析——父组件传递子组件,子组件传递父组件。

react渲染原理

React 是一个基于组件的 JavaScript 库,用于构建用户界面。React 的主要原理是将用户界面抽象为一组嵌套的组件,每个组件都拥有自己的状态和行为。当组件的状态发生改变时,React 会自动重新渲染组件,并将更新后的组件插入到 DOM 树中。

React 的渲染过程主要涉及以下几个步骤:

  1. 首先,React 会根据 JSX 语法解析出虚拟 DOM(Virtual DOM)对象树,该虚拟 DOM 对象树只是一个 JavaScript 对象,其中包含了组件的状态、属性和子节点等信息。
  2. 然后,React 通过比较新旧虚拟 DOM 对象树,找出需要更新的部分,只更新需要更新的部分,称之为 “DOM Diff”。
  3. 接着,React 调用 render 方法生成新的虚拟 DOM 对象树,并将其与旧的虚拟 DOM 对象树进行比较。
  4. 如果新旧虚拟 DOM 对象树相同,则不进行任何操作。
  5. 如果新旧虚拟 DOM 对象树不同,则根据差异进行更新,生成新的虚拟 DOM 对象树。
  6. 最后,React 将更新后的虚拟 DOM 对象树渲染到真实的 DOM 上,完成渲染过程。

React 的渲染过程主要基于虚拟 DOM 和差异化算法。通过虚拟 DOM 对象树的比较,React 能够高效地进行局部更新,提高了应用程序的性能和用户体验。

vue渲染原理

Vue的渲染原理可以大致分为以下几个步骤:

  1. 解析模板:Vue会将模板字符串解析成抽象语法树(AST),这个过程中会标记出模板中的所有指令、插值语法、事件等信息。这一步由模板编译器完成。
  2. 根据AST生成渲染函数:Vue会从抽象语法树中生成一个可执行的渲染函数(render function),这个函数可以接收一个参数——渲染上下文(render context),并返回一个VNode节点。
  3. 渲染函数执行:当组件需要重新渲染时,Vue会执行渲染函数,生成一个新的VNode节点树。
  4. Diff算法对比新旧VNode:Vue将上一步生成的新VNode节点树和上一次渲染的旧VNode节点树进行对比,通过Diff算法找出需要更新的节点。
  5. 生成补丁(patch):Diff算法找出需要更新的节点后,会生成一个补丁对象(patch),这个补丁对象描述了要对哪些节点进行何种修改操作。
  6. 将补丁应用到真实的DOM上:最后,Vue将生成的补丁对象应用到真实的DOM节点上,完成组件的更新。

注:以上是Vue2.x版本的渲染原理,Vue3.x版本的渲染原理有所不同,主要是采用了基于Proxy的响应式数据自动更新机制以及模板编译器与运行时渲染器分离等新特性。

⭐react 组件传值实例

项目截图

💖父组件传值给子组件(props)

App.tsx通过标签内属性传递editInstance给EmailPage.tsx

父组件 App.txs

传递一个grapesjs实例到EmailPage

import './App.css';
import 'grapesjs/dist/css/grapes.min.css';
import grapesjs from 'grapesjs';
function App() {
  return (
      <div className="App">
        <EmailPage editInstance={grapesjs} ></EmailPage>
      </div>
  );
}
export default App;

子组件 EmailPage.tsx 解构props

解构接收props的editorInstance

import grapesJSMJML  from '../components/email-edit/index'
import { forwardRef, useEffect, useState,useImperativeHandle } from 'react'
const EmailPage=(props:any)=>{
    const [editor,setEditor]=useState();
    useEffect(()=>{
        const editorInstance:any = props.editInstance
            .init({
                fromElement: true,
                container: '#gjs-email',
                plugins: [grapesJSMJML ],
            });
        try{
            editorInstance.Commands.run('mjml-clear')
        }
        catch (e) {
            console.error('e',e)
        }
        setEditor(editorInstance)
    },[props.editInstance])
    return (
        <div id={'gjs-email'} className={'design-editor'}/>
    )
}
export default EmailPage;

💖子组件传递事件给父组件props绑定事件

同理我们也可以在props传递一个事件给props,在子组价触发即可

💖父组件触发子组件的事件Ref

父组件 App.txs 使用ref获取组件实例

import './App.css';
import 'grapesjs/dist/css/grapes.min.css';
import grapesjs from 'grapesjs';
import { useState,useEffect,useRef } from 'react';
function App() {
  const emailRef:any=useRef();
  useEffect(()=>{console.log(emailRef)},[emailRef])
  return (
      <div className="App">
        <EmailPage editInstance={grapesjs} ></EmailPage>
      </div>
  );
}
export default App;

子组件 EmailPage.txs使用useImperativeHandle 暴露方法和属性

暴露两个方法分别是 getHtml和getBodyContent,最后使用forwardRef抛出组件实例

import grapesJSMJML  from '../components/email-edit/index'
import { forwardRef, useEffect, useState,useImperativeHandle } from 'react'
import zh from "../components/email-edit/locale/zh";
const EmailPage=(props:any,ref:any)=>{
    const [editor,setEditor]=useState();
    const [domRef,setDomRef]=useState();
    useEffect(()=>{
        const editorInstance:any = props.editInstance
            .init({
                fromElement: true,
                container: '#gjs-email',
                plugins: [grapesJSMJML ],
            });
        try{
            editorInstance.Commands.run('mjml-clear')
        }
        catch (e) {
            console.error('e',e)
        }
        setEditor(editorInstance)
    },[props.editInstance])
    const getBodyContent=()=>{
        // @ts-ignore
        const inlineHtml=editor.Commands.run('mjml-code-to-html-inline')
        const matchBody=new RegExp('<body[^>]*>([\\s\\S]+?)<\\/body>','ig');
        const matchBodyText=inlineHtml.match(matchBody)
        // @ts-ignore
        return matchBodyText?matchBodyText[0]:''
    };
    const getHtml=()=>{
        // @ts-ignore
        return editor.Commands.run('mjml-code-to-html-inline')
    }
    useImperativeHandle(ref, () => ({
        getHtml:getHtml,
        getBodyContent:getBodyContent
    }));
    return (
        <div id={'gjs-email'} className={'design-editor'}
             ref={(ref:any)=>{
                 setDomRef(ref)
             }}
        />
    )
}
export default forwardRef(EmailPage);

⭐vue3 组件传值实例

项目截图

💖 父组件传递数据给子组件props

子组件 defineProps 定义接受的参数

IframeContent.vue

<template>
  <div class="iframe-container">
    <div class="iframe-content" v-if="!isPage&&!isModel">
      <div style="width: 100%">
        <span> 标题:{{ title }} </span>
        {{kind}}
        <a-button
          @click="jumpPage"
          type="primary"
          style="float: right; margin: 5px"
        >
          跳转</a-button
        >
      </div>
      <iframe :src="url" class="iframe-box"></iframe>
    </div>
    <div class="iframe-content" v-else-if="!isModel">
      <UserTable></UserTable>
    </div>
    <div class="iframe-content" v-else>
      <ChatTable></ChatTable>
    </div>
  </div>
</template>
<script lang="ts" setup>
import {computed} from 'vue'
// @ts-ignore
const props = defineProps<{
  url: string;
  title: string;
  kind: string;
}>();
const isPage=computed(()=>{
  console.log('props',props)
  return props.kind=='page'
})
const isModel=computed(()=>{
  console.log('props',props)
  return props.kind=='model'
})
const emit = defineEmits<{
  (e: "change", id: number): void;
  (e: "update", value: string): void;
}>();
const jumpPage = () => {
  window.open(props.url);
};
</script>

父组件 标签内传递数据给子组件

传递参数给iframe-content组件

<script setup lang="ts">
// @ts-ignore
import IframeContent from "../iframe/IframeContent.vue";
import { reactive} from "vue";
interface contentType {
  url: string;
  title: string;
  kind:string;
}
const contentConfig: contentType = reactive({
  url: "url",
  title: "title",
  kind:'kind'
});
</script>
<template>
  
          <iframe-content
            :url="contentConfig.url"
            :title="contentConfig.title"
            :kind="contentConfig.kind"
          />
</template>


vue3、react组件数据传值对比分析——父组件传递子组件,子组件传递父组件(二)https://developer.aliyun.com/article/1492685


目录
相关文章
|
13天前
|
缓存 前端开发 JavaScript
【亮剑】在React中如何通过点击事件控制组件显示与隐藏,包括基础概念和高级应用
【4月更文挑战第30天】本文介绍了在React中如何通过点击事件控制组件显示与隐藏,包括基础概念和高级应用。使用`useState`钩子和Context API可实现状态驱动的条件渲染,通过CSS类控制组件样式,或利用React Portals在DOM不同位置渲染。性能优化应注意避免不必要的渲染、合理使用Keys、优化事件处理器、使用Memoization及清理资源。测试和验证确保逻辑正确性,以构建动态用户界面并提升应用性能。
|
16天前
|
开发框架 前端开发 JavaScript
【专栏】对比分析两种流行的跨平台开发框架——Flutter和React Native,探讨它们的优势、劣势以及适用场景
【4月更文挑战第27天】本文对比分析了Flutter和React Native两大跨平台移动开发框架。Flutter,由Google推出,以其接近原生的性能、快速启动和流畅滚动受青睐,适合高性能和高度定制的项目。React Native,Facebook维护,依赖JavaScript,虽性能受限,但热重载优势和丰富第三方库使其适合快速迭代的项目。两者都在拓展多平台应用,Flutter在桌面和Web,React Native在Windows。选择框架需考虑项目需求、团队技能和性能效率平衡。
|
18天前
|
前端开发 JavaScript 开发者
vue3、react组件数据传值对比分析——父组件传递子组件,子组件传递父组件(二)
vue3、react组件数据传值对比分析——父组件传递子组件,子组件传递父组件
22 0
|
18天前
|
存储 前端开发 JavaScript
React的表单处理:受控组件与非受控组件深入解析
【4月更文挑战第25天】React表单处理涉及受控和非受控组件。受控组件通过状态管理表单数据,每次用户输入都触发状态更新,确保数据同步,适合实时交互但可能影响性能。非受控组件不直接管理状态,数据存储在DOM中,简化代码,适用于更新不频繁的场景,但在数据验证和同步上存在挑战。开发者应根据需求灵活选择。
|
18天前
|
前端开发 JavaScript 开发者
React的函数组件与类组件:探索两者之间的区别
【4月更文挑战第25天】React提供函数组件和类组件,两者在语法、状态管理、生命周期和性能优化上有所不同。函数组件简单且易于理解,使用 Hooks 可添加状态管理;类组件支持复杂状态管理和生命周期方法,适用于需要精细控制更新的场景。随着 Hooks 的发展,函数组件功能增强,成为更多开发者的首选。选择组件类型应根据实际需求权衡。
|
18天前
|
设计模式 前端开发 API
React的高阶组件(HOC):使用与设计模式探讨
【4月更文挑战第25天】React的高阶组件(HOC)是一种复用和增强组件的高级模式,它接受组件并返回新组件。非侵入式增强使得HOC能在不修改原有组件代码的情况下添加功能。定义HOC后,将其应用于目标组件并渲染增强后的组件。常见设计模式包括属性代理、控制反转和装饰器。然而,使用时要注意避免滥用,保持命名清晰,关注性能优化。理解并恰当使用HOC能提升React应用的构建效率。
|
19天前
|
前端开发
探索React Hooks:一种全新的组件逻辑管理方式
React Hooks是React 16.8版本引入的一项新功能,它改变了我们编写React组件的方式。本文将从Hooks的起源讲起,逐步分析Hooks的优势,并通过具体示例展示Hooks在组件逻辑管理中的应用,旨在帮助读者更好地理解和运用React Hooks。
|
1月前
|
JavaScript 前端开发
【干货分享】选择 Vue 还是 React?项目框架选择的实际分析
【干货分享】选择 Vue 还是 React?项目框架选择的实际分析
|
1月前
|
前端开发 JavaScript Android开发
框架分析(8)-React Native
框架分析(8)-React Native
|
1月前
|
设计模式 前端开发 JavaScript
框架分析(2)-React
框架分析(2)-React