当前位置: 首页 > Web前端 > HTML5

vue2源码框架及流程分析

时间:2023-04-05 19:31:12 HTML5

vue整体框架及主要流程分析之前看了很多vue源码的文章,但是整体框架和流程还是有点模糊,最后使用chromedebug查看和整理一下vue源码这篇文章。...本文简单分析了vue的整体框架和整体流程,一些具体的细节就不分析了。都需要对vue有一个初步的了解,包括对Object.defineProperty和virtualDOM有一定的了解。本文不讨论对象。defineProperty,分析了虚拟DOM的原理和细节。Vue大致可以分为两部分:1.使用Object.defineProperty进行数据的双向绑定;2、使用虚拟DOM技术进行视图渲染;vue入口vue构造函数调用this._init(options)方法,该方法在initMixin中,如上图,进入initMixininitMixin主要完成数据和视图的初始化:1.数据初始化主要是对数据的观察,在上图中的initState中进行;2.view的初始化是在vm.$mount(vm.$options.el)中,其中vm是Vue的一个实例,watcher的设置也是在vm.$mount(vm.$options.el));我们可以看到这里定义了beforeCreated和created两个钩子函数。数据初始化接下来我们看看上面的数据初始化都做了什么。当我们进入initState时,主要是对数据进行操作。InitData是传入的,我们来看一下initData:我们忽略前面的一些逻辑判断,主要看两个地方:1.数据代理,主要是将_data的数据代理给vm,这样可以直接修改数据在虚拟机上;2.数据观察,传入数据;我们先看看vue是如何处理观察到的数据的。输入observe返回ob,它是Observer类的一个实例。让我们看看Observer类是如何定义的。进入Observer类,如上图,在观察数据时对数组进行特殊处理,先不看这块,先看一般处理,即调用this.walk(value)walk主要是遍历数据的属性,进入defineReactive可以看到Object.defineProperty是在这里设置get的,对于属性设置是的,这里get主要是收集依赖,其实就是一个收集view渲染的watcher。后面会提到,set主要是在数据更新的时候更新视图。至此,数据的初始化就完成了。从上面的分析来看,数据初始化的主要工作是观察数据。视图挂载跟上,在vue入口,我们知道视图的挂载主要是调用vm.$mount(vm.$options.el)如图,所以我们输入vm.$mount看看是什么里面做了什么,源码中有两处地方涉及到$mount。这是第一个地方,就是returnmountComponent。这是第二个地方。上面两张图是在一起的,屏幕尺寸有限,所以拍了两张。..再来看第二个地方,这里做了一个过程,就是把模板编译成render函数,vue教程中用到的。这里我们可以看到在组件中定义渲染函数会比定义模板更快。因为在挂载定义模板的组件时,多了一个将模板编译成render函数的步骤;第二处的return还是调用了第一处,那么我们看一下第一处调用的mountComponent方法,进入mountComponent。上面两张图是在一起的,屏幕大小有限,所以截了两张。..这里我们可以看到定义了两个钩子beforeMount和mount,中间调用了watcher。我们先看看这里watcher的定义。这里的注释不太好,屏蔽了。..我们看一下watcher的这行代码:vm._watcher=newWatcher(vm,updateComponent,noop)我们可以看到Watcher类主要传入了三个参数:vm、updateComponent和noop,updateComponent的main函数就是将虚拟DOM转换成真实DOM并挂载。具体细节在下面讨论。我们来看看Watcher类是如何定义的。当我们进入Watcher时,我们要注意两个地方。一个是this.getter的定义,是从上面传入的。updateComponent,并执行this.get(),我们进入这个get方法,这里我们看到首先收集到的依赖是当前的watcher实例,然后调用getter方法,也就是updateComponent方法,之前我们简单解释一下函数updateComponent方法说明,这里我们看updateComponent做了什么,进入updateComponent:这里调用了vm._update方法,传入的参数是vm._render(),_render函数的主要作用是生成虚拟DOM,输入_update这个主要是将虚拟DOM转换为真实DOM并挂载。有两种情况,一种是有旧的虚拟DOM,一种是没有旧的虚拟DOM,对应初始化时或者更新数据时调用。这里定义了一个钩子beforeUpdate。至此,视图的初始化和挂载也结束了。我们来看看当数据发生变化时视图是如何更新的。数据变化时的视图更新过程。接下来,让我们看看当数据发生变化时,视图是如何变化的。在初始化数据的时候,我们知道当数据发生变化时会触发set方法,如下图:从上图可以看出,set最终调用了dep.notify,如图进入notify上面notify主要是收集dependencies,也就是收集所有的watcher,并调用所有watcher的update方法,我们看看watcher的update方法做了什么。这里是调用queueWatcher,这里进入queueWatcher,使用队列的异步更新,即将watcher推入队列,然后执行nextTick方法,进入nextTick。上面两张图是在一起的,屏幕大小有限,所以截了两张。..这部分有点难看,cb是传入flushSchedulerQueue函数,执行timerFunc,将nextTickHander加入异步队列,执行nextTickHander,执行cb,都执行flushSchedulerQueue,进入flushSchedulerQueue上面两张图在一起,屏幕大小有限,所以我截了两张图。..主要看watcher.run(),进入watcher.run执行this.get(),也就是进入到之前数据渲染挂载的地方,vue的整个执行过程就基本结束了。vue流程图从vue官网盗取了vue生命周期的图,和之前的内容对比一下:基本上每个hook函数的位置通过上面的分析对比就可以找到了,我不需要分析下面被破坏的那个。..有兴趣可以关注我的博客