当前位置: 首页 > Web前端 > vue.js

教你阅读vue源码的正确姿势,看完学会浪费!

时间:2023-03-31 16:47:46 vue.js

介绍一下我阅读vue源码的姿势。有什么建议欢迎在评论区补充哦~1.源码阅读姿势1.先整体-再详细,先搞清楚源码分为哪些模块,整个流程是怎么分的模块串在一起。然后细化对每个模块核心原理的理解。2.站在别人的肩膀上,一点都不用去源码仓库里扎,效率很低。适合对源码比较了解的人。各部分的通用功能和核心流程。带着心里的想法去看了源码实现。大多数情况下,一行一行的代码是不需要研究的,但是一些核心功能的实现需要仔细研究,比如:虚拟dom,diff算法,数据驱动,响应式实现,组件化。建议仔细看看核心功能的核心实现。3、多读多读,粗读:看整体流程,看每个模块的核心功能和职责,体会自己平时在源码中写的代码在页面上体现了哪些步骤。第二精读:看实现细节,搞清楚核心模块的实现(比如理解diff算法的思想,最好自己实现)。三看:理解源码的整体结构和设计思路,理解各个模块是如何相互配合、协作的,结构是如何组织的。2.步骤依赖分析组装:路由,父子组件层级模板编译:解析成AST语法树,然后构建虚拟dom树加载页面:将虚拟dom整体转化为真实dom部分更新:响应式数据监听变化、diff比较数据变化前后虚拟dom树的区别、部分更新dom销毁:销毁虚拟dom、移除dom3、vue源码指南模板风格、对象配置风格虚拟dom思路(js对象操作代替dom操作)diff算法思想(同层比较、增、移、删)组件思想(组件编译、组件通信)数据响应(依赖收集、分发更新、发布订阅)4.vue3新特性理解vue2.x的痛点:源代码本身的可维护性;大量数据渲染和更新后带来的性能问题;一些我想放弃但为了兼容性而保留的鸡肋API;打字稿支持;vue3.0优化点:1.使用monorepo管理源码2.使用TypeScript开发源码3.性能优化1.源码体积优化2.数据劫持优化Proxy3.编译优化4.Diff算法优化4.语法API优化:CompositionAPI插一句题外话,小编整理了使用Vue3.0写小程序框架的PDF资料,谢谢有兴趣的朋友请点这里领取5.仔细看看diff算法。vue2的diff组件更新的核心是响应式数据监听数据变化,重新生成虚拟dom树,然后通过diff算法计算前后虚拟dom树的差异点,只有变化的部分才更新dom已更新。快速提问和快速回答:1.为什么要区分?答:O(n^3)的意思是如果要显示1000个节点,必须依次进行数十亿次比较,无法承受大数据量的比较。为什么直接比较修改两棵树的复杂度是n^3?答:旧树的每个节点都遍历新树的节点,直到找到新树对应的节点。那么这个过程就是O(n^2),然后求差之后,计算最短修改距离,然后修改节点,这里是O(n^3)。2、diff的策略是什么?依据是什么?答:1、WebUI中DOM节点的跨层级移动操作很少,可以忽略,所以只做同层比较。2.如果父节点不同,则放弃子节点的比较,直接删除旧节点添加新节点重新渲染;3.如果子节点发生变化,VirtualDOM不会计算发生了什么变化,而是重新渲染。4.多个同级节点可以通过一个唯一的key来比较异同;3.什么是diff过程?答:新旧节点不同:新建节点?更新父占位节点?删除旧节点;新旧节点相同且没有子节点:不变;新旧节点相同且有子节点:遍历子节点进行同级比较,移动、添加、删除三个操作,详见下图;vue3.0的diffdepth递归遍历vnode树,如果节点的label和key相同,则认为是同一个节点则更新,不同则删除,然后子节点将被处理。处理子节点有几种情况:纯文本、vnode数组、空常表示增删;明文相同则直接更新innerText,不同则删除;如果新旧子节点都是vnode数组,那么diff算法会处理;vue3.0diff算法的思想是在编译模板时进行静态分析,标记动态节点,比较差异时只比较动态节点(性能提升明显);diff算法首先去掉头尾,从而缩短遍历比较数组的长度(对于数组的插入和删除操作,性能优化明显);通过为更新前后的子节点数组建立映射表,将遍历的O(n^2)复杂度降低为O(n);diff前后的子节点采用最长增量子序列方法Array获取,减少移动操作次数;最长递增子序列算法实现:/**寻找最长递增子序列*使用动态规划思想,a->c=a->b+b->c*其中p数组存放的是从p开始的最长递增子序列索引[p[i]]到p[i],即前一个b的索引;*r数组存储最后一个元素,也就是c的索引*/functiongetSequenceOfLIS(arr){constp=[0];常量结果=[0];for(leti=0;i>1;如果(arr[结果[c]]0){p[i]=result[l-1]}result[l]=i;}}//返回p数组,找到最长的递增子序列letpreIndex=result[result.length-1];对于(leti=result.length-1;i>0;i--){result[i]=preIndex;preIndex=p[preIndex]}returnresult;}阅读vue源码姿势,小伙伴们学会使用了吗?小伙伴们记得领取哦!点这里也和领取一样,请点赞支持!星期五快乐,我的朋友们!