本文转自:乐字节文章主要讲解:Vue实现原理更多VUE相关资料和项目可以关注公众号《乐字节》发送:9991,Vue简介在当下的大前端时代,是一个纷扰纷争的时代。世界上已经分成了很多门派,主要以Vue、React和Angular为首,形成了前端框架三足鼎立的局面。Vue在前端框架中的地位就像过去的jQuery。由于其简单、开发效率高,已经成为前端工程师的必备技能之一。Vue是一个渐进式JavaScript框架,完美集成了第三方插件和UI组件库。它与jQuery最大的不同在于,Vue无需开发者直接操作DOM节点就可以改变页面渲染内容。基于HTML、CSS、JavaScript,快速上手,开发优雅简洁的应用模块。但是我们一提到Vue,更多的是关注它的用法,而不是去学习它是如何解决前端问题的,这就有些亚健康了。有过前端开发经验的人,肯定在开发过程中遇到过奇怪的问题,然后迷迷糊糊解决了。如果他们再次遇到类似的问题,他们将再次不知所措。作为一名前端工程师,在遇到问题时,能否准确定位问题原因并及时解决,主要取决于我们对前端框架的理解是否足够深入。2.Vue实现原理2.1虚拟DOM(VirtualDOM)随着时代的发展,web应用的页面交互效果越来越复杂,页面功能越来越丰富,需要的状态也越来越多需要维护,DOM操作也越来越复杂。更频繁。DOM操作虽然简单易用,但是会带来维护性差的问题。在程序执行过程中,Watcher会在初始化时将各个节点和状态一一关联映射。setter检测到Data的状态发生变化后,会通知Watcher,Watcher会将这些变化通知给之前记录的DOM。以及与这些状态相关的节点,从而触发页面的渲染过程。组件接收到状态变化后,会通过编译将模板转换为渲染函数Render,并执行渲染函数得到一棵虚拟DOM树。通过比较旧的虚拟DOM和新生成的虚拟DOM树,更新对应的实际DOM节点。,执行页面渲染。几乎所有的主流前端框架都使用虚拟DOM,但是在使用虚拟DOM时,无论是Angular还是React都无法确定哪个状态发生了变化。因此,需要对旧的虚拟DOM和新的虚拟DOM进行一次暴力比较。但是,Vue从1.0版本开始通过细粒度绑定来更新视图。也就是说,当状态发生变化时,Vue可以知道哪些状态需要变化,哪些节点需要变化,从而更新节点。但是,这种细粒度的变化检测有一定的内存开销影响性能,而且项目越复杂,开销越大。Vue2.0版本之后,为了优化性能,引入了虚拟DOM,选择了一个折中方案。它既不需要暴力比较整个新旧虚拟DOM,也不需要通过细粒度绑定来更新视图,即以Components为单位进行Watcher监控,也就是说,即使多个组件中的节点使用某种状态,只需要一个Watcher来监听这种状态的变化。当状态改变时,Watcher通知组件,组件内部通过虚拟DOM来比较和重新渲染节点。2.2常用指令的实现原理指令是指Vue提供的带有“v-”前缀的特性。当指令中表达式的内容发生变化时,会影响DOM内容的变化。Vue.directive全局API可以创建自定义指令和获取全局指令。除了自定义指令,Vue还有一些开发过程中常用的内置指令,比如v-if、v-for等,在解析Vue模板时,指令会被解析成AST,而函数该指令的实现将在使用AST生成字符串的过程中实现。在解析模板时,节点上的指令将被解析并添加到AST的directives属性中。这些指令会将数据发送到VNode。当虚拟DOM渲染页面时,会触发一些钩子函数。当钩子函数被触发后,就表示命令生效了。2.2.1v-if指令原理在应用中使用v-if指令:编译阶段产生:代码执行时会根据create的值选择创建哪个节点。2.2.2v-for指令原理在应用中使用v-for指令:编译阶段产生:_l是renderList的别名。当代码执行时,_l函数会循环列表变量并调用传入第二个参数的函数。传递两个参数:item和index。当调用_c函数时,会执行_v函数创建一个节点。2.2.3自定义指令的原理在应用程序中,指令的处理逻辑分别监控创建函数、更新函数和销毁函数。具体实现如下:触发钩子函数后,会执行updateDirectives函数。代码如下:在这个函数中,不管是否有旧的虚拟节点,只要有指令,就会执行_update函数。_update函数的代码如下:isCreate:判断虚拟节点是否为新创建的节点。isDistory:判断是否删除旧的虚拟节点。oldDirs:旧命令集,oldVnode中保存的命令。newDirs:新指令集,指令保存在vnode中。dirsWithInsert:触发插入命令的钩子函数的命令列表。dirsWithPostpatch:触发componentUpdated钩子函数的指令列表。通过normalizeDirectives函数从用户注册的自定义指令集合中提取模板中使用的指令,结果如下:自定义指令的代码为:虚拟DOM比较渲染时,会根据不同触发不同的钩子函数到不同的场景。当使用虚拟节点创建新的实际节点时,会触发创建钩子函数,当向父节点插入DOM节点时,会触发插入钩子函数。callHook函数执行钩子函数的方式如下:callHook函数的参数含义为:dir:指令对象。hook:要触发的钩子函数的名称。vnode:新的虚拟节点。oldVnode:旧虚拟节点。isDestory:判断是否删除旧的虚拟节点。虚拟DOM在渲染过程中会触发的所有钩子函数及其触发机制如下:需要注意的是,remove函数只会在元素从其父元素中移除时触发,如果该元素是子元素被移除的element元素,remove函数不会被触发。感谢大家的认可和支持,小编会继续转发《乐字节》的优质文章
