总览
Vue | React | |
---|---|---|
组件 | 单文件组件:使用template、script和style来分别定义组件的结构、逻辑和样式。 | 在React中,组件可以通过函数式组件或类组件来定义。 |
思想 | 数据的响应式:当数据发生变化时,Vue会自动更新相关的DOM | React 的核心思想是每次对于变更 props 或 state ,触发新旧 Virtual DOM 进行 diff(协调算法),对比出变化的地方,然后通过 render 重新渲染界面。 |
状态或变量响应式渲染 | Vue使用响应式系统来实现状态或变量的响应式渲染。 当数据发生变化时,Vue会自动更新DOM。 这是通过Vue的响应式原理实现的,即Vue在初始化时将数据转换为getter/setter形式的对象,当数据变化时,setter会触发组件的重新渲染。 |
React通过setState方法来更新组件的状态,并触发组件的重新渲染。 React使用一种名为“调和”(Reconciliation)的过程来比较新旧虚拟DOM树,并计算出最小的DOM更新。 当组件的状态或属性发生变化时,React会重新渲染该组件及其子组件。 |
数据流 | 单向数据流 | 单向数据流 |
组件通信(父子组件通信) | 通过props和emit进行:父组件通过props向子组件传递数据或回调,子组件则通过emit触发事件来向父组件发送消息。 | 通过props和回调函数实现:父组件通过props将数据或函数传递给子组件,子组件则可以通过这些props来接收数据和触发回调函数 |
Prop逐级透传问题(跨组件通信) | Vue通过provide 和inject 机制解决Prop逐级透传问题。父组件使用 provide 提供数据或方法,子组件通过inject 接收。 |
React没有内置的Prop逐级透传机制,通常通过高阶组件或Context API来实现。 高阶组件是一种函数,它接收一个组件并返回一个新组件,新组件可以访问传递的props。 Context API提供了一种在组件树中共享值的方式,无需显式地通过每一层组件。 |
子组件渲染 | Vue插槽是一种组件间内容分发机制,允许父组件将内容传递给子组件的指定位置。 通过 <slot> 标签定义插槽的位置,父组件使用<template> 标签包裹内容,并通过具名插槽或作用域插槽将内容传递给子组件。 |
React通过 JSX children 属性直接将组件标签内的内容作为prop传递给子组件。 组件标签内的内容会自动成为 children prop,父组件可以将内容直接传递给子组件,并在子组件内部通过props.children 或函数组件的props参数访问。 |
模板引用 | Vue2中:模板中的元素或组件上使用ref 属性,在Vue实例的方法或生命周期钩子中通过this.$refs 来访问。Vue3中:模板中使用 ref 函数来创建引用,在 setup 函数中通过 import { ref } from 'vue'; 创建 ref 模板同名 ref 变量引用模板。 |
useRef 钩子来创建引用,通用 JSX 使用 ref = ref变量名 进行引用 |
传送门 | Teleport:引入了 <Teleport> 组件,将子组件渲染到 DOM 树中不同于其父组件位置的能力 |
Portals:通过createPortal 允许你将 JSX 作为 children 渲染至 DOM 的不同部分 |
生命周期 | Vue 2.x有beforeCreate 、created 、beforeMount 、mounted 、beforeUpdate 、updated 、beforeDestroy 和destroyed 等生命周期钩子。Vue 3.x引入了Composition API,提供了 onMounted 、onUpdated 、onUnmounted 等函数式API来替代部分生命周期钩子。 |
React有constructor 、componentDidMount 、componentDidUpdate 、componentWillUnmount 等生命周期方法。在React 16.8及以后的版本中,引入了Hooks API(如 useEffect 、useState 等),使得在没有类的情况下使用状态以及其他React特性成为可能。 |
逻辑复用 | Vue3中采用组合式 API 逻辑组织能力 | React 中采用 React Hooks |
虚拟DOM | 带编译时信息的虚拟 DOM | 纯运行时虚拟 DOM |
JSX 语法 | 通过 @vue/babel-plugin-jsx 插件支持,语法与React JSX 不同,参考以下比较 |
默认支持 |
函数式组件 |
About 29 min