基于PCA9422与PIC18F46K42的低功耗电源管理方案设计
2026/10/24 3:08:10
| 维度 | Vue 3 | React 18 |
|---|---|---|
| 核心定位 | 渐进式 MVVM 框架 | 只负责 View 的 UI 库 |
| 语法范式 | 单文件组件:template + script + style;支持选项式 + 组合式(setup) | 函数组件 + Hooks; 原生JS + JSX编程; |
| 数据绑定 | 响应式(Proxy 拦截,自动追踪依赖) | 手动 setState/ useState,不可变数据流 |
| 组件更新机制 | 依赖追踪 + 异步队列批量更新(nextTick) | Fiber + 调度器(lane 模型),时间切片 |
| 内置特性 | v-model、指令、keep-alive、transition、teleport 等官方内建 | 无内置高级特性,全由社区提供 |
| 状态管理 | Pinia、Vuex | Redux、MobX、Zustand、Recoil、Jotai |
| 路由 | Vue Router(官方) | React Router(社区) |
| 构建工具 | Vite(官方默认) | 自由选型:Create-React-App、Vite、Next.js、Remix |
| 生态周边 | 官方维护:Router、Pinia、DevTools、VSCode 插件 | 社区主导:选择多但碎片化 |
| 典型使用场景 | 后台管理系统、中后台、渐进式升级老项目 | 大型 SPA、跨平台(React Native)、Node 同构(Next.js) |
| 维度 | Vue 3 | React 18 |
|---|---|---|
| VDOM 结构 | 组件级 VNode + 块(Block)树 | 纯 Fiber 链表(vNode = FiberNode) |
| 更新触发 | 响应式系统(Proxy)精准收集依赖,仅受影响的组件重新渲染 | setState/useState手动触发,父组件更新默认带动所有子组件(除非 React.memo) |
| Diff 算法 | 编译期静态标记+ 动态补丁(patch flag)→ 只 Diff 动态节点 | 全树 Diff(双指针遍历 Fiber 链表),跳过 keyed 节点用 Map 加速 |
| 静态提升 / Block | 编译期把静态节点提升为常量,生成 Block 树,Diff 时跳过静态部分 | 无静态提升,每次 Diff 都遍历整棵子树(开发者需手动 memo) |
| 时间切片 | 无(更新是同步微任务,nextTick 批量) | 有(Fiber lane 模型 + Scheduler)可中断/恢复 |
| 编译期优化 | 模板编译成render 函数 + patchFlag,运行期只做最小 patch | JSX 编译成createElement 调用,运行期无法区分静动态 |
虚拟DOM 主要是用JavaScript 对象(VNode)描述真实 DOM 结构,通过 Diff 算法比较新旧 VNode (虚拟节点)树,找出最小差异并批量更新真实 DOM
interfaceVNode{type:string|Component// div 或组件定义props:Object|null// 属性/事件children:VNode[]|string|null// 子节点key:string|number|null// Diff 标识el:Element|null// 对应真实 DOM(挂载后)}import{h}from'vue'// 写法 ① 模板<div id="app">{{msg}}</div>// 写法 ② 渲染函数 = 产生 VNoderender(){returnh('div',{id:'app'},this.msg)}functionpatch(oldVNode,newVNode,container){// ① 类型不同 → 直接替换if(oldVNode.type!==newVNode.type){replaceNode(oldVNode,newVNode,container)return}// ② 类型相同 → 更新 props & 递归 childrenpatchProps(oldVNode.props,newVNode.props,el)patchChildren(oldVNode.children,newVNode.children,el)}functionpatch(oldVNode,newVNode,container){if(oldVNode.type!==newVNode.type){replaceNode(oldVNode,newVNode,container)// 类型不同直接替换return}patchProps(oldVNode.props,newVNode.props)// 属性差异更新patchChildren(oldVNode.children,newVNode.children,container)// 子节点 Diff}letoldStart=0,oldEnd=oldChildren.length-1letnewStart=0,newEnd=newChildren.length-1// ① 双端预处理:头-头、尾-尾、头-尾、尾-头while(oldStart<=oldEnd&&newStart<=newEnd){if(isSameVNode(oldChildren[oldStart],newChildren[newStart])){patch(oldChildren[oldStart],newChildren[newStart],container)oldStart++;newStart++}elseif(isSameVNode(oldChildren[oldEnd],newChildren[newEnd])){patch(oldChildren[oldEnd],newChildren[newEnd],container)oldEnd--;newEnd--}else{break}// 预处理结束,跳出}// ② 建立 key → oldIndex 映射constkeyToOldIndex=newMap()for(leti=oldStart;i<=oldEnd;i++){keyToOldIndex.set(oldChildren[i].key,i)}// ③ 遍历剩余新子序列,记录可复用旧节点constnewIndexToOldIndex=[]// 下标 = 新序列位置,值 = 旧序列位置letmoved=false,lastIndex=0for(leti=newStart;i<=newEnd;i++){constnewChild=newChildren[i]constoldIndex=keyToOldIndex.get