VUE2 源码核心流程

源码基本目录结构:
在这里插入图片描述

1.初始化状态

1.入口文件 index.js ,vue函数接收用户执行vue函数时传入的参数,在导入这个index.js 文件时,
开始初始化 ,给Vue原型上添加方法分别有update方法 render方法 混合全局api 扩展初始化方法。

2.initMixin 方法 传入Vue函数 给Vue原型上添加了_init的方法, 用户执行Vue函数时就会调用_init方法
_init方法接收用户参数 将用户传入的options绑定到this上 这个this(下文使用vm代替)就是用户new Vue的实例 

3.initState(传入vm) 初始化用户的参数 初始化的顺序 props methods data computed watch 
(有时候面试官会喜欢问一下)
初始化data数据将data数据变成响应式 initData 传入vm

2.数据响应式

1.使用vm获取到用户传入的options 取到data属性, data的写法如果是函数形式 那么就使用.call指向传入的vm 
拿到返回值 
如果不是函数形式就是对象了不处理, 将数据绑定到data 和 vm._data(绑定到_data统一管理)上

2.将data上的数据for in循环取到key 使用definedProperty 用户实列取key的时候其实取得是_data中的key,
 做了个中间转发,这样做的好处就是vm上也能直接通过key值取到对应得数据

3.观测数据Observe(data) ,只对对象类型进行观察 非对象类型不观测

4.给观测数据 数组或对象添加dep属性

5.给当前的数组或者对象绑定__ob__ 属性 设置不可枚举( enumerable)删除(configurable),
判断当前值是数组还是对象

6.数组处理:
	数组的修改不外乎方法,数组直接下标修改是不做响应式的(如果给数组的下标做成响应式,过于消耗性能)
	不能直接修改Array的方法 只修改vue中数组的方法, 使用Object.create复制一份Array的方法
	我们改写的方法有7个 push pop unshift shift splice reverse sort 这些方法都是会修改数组的方法
	push unshift splice 方法获取传入的参数 因为数组传入的数据也有可能是对象或数组 需要再次拦截
	
	每次调用这些方法就调用deep ,在初始化时就已经给对象和数组绑定了deep,
	将处理好后的数组绑定到当前数组上

7.对象处理:
	对象处理就是把用户给的每一数据都进行响应式的,用户写的就规定了一定是对象。
	对象的响应式就是使用defineProperty 进行 监听到每次数据的变化。
	需要注意的是用户传入的值也可能是个对象,所以也需要响应式

	对象是存取值得时候,存得时候让deep 记住watcher 设置值得时候让deep去执行watcher
8.关于dep与watcher: 
	dep的作用:
		最主要就是能够记住当前的watcher 也能让当前watcher执行,
		并且deep能够让watcher 记住当前的deep
	
	watcher的作用: 
		每个组件都有一个渲染watcher, 当dep是可以去执行watcher的
		watcher中可以记住deep 使用new set进行去重。  这样每次存入的deep就不会重复, 
		deep不重复那么watcher存的时候也是存入不同的deep 所以watcher也不会重复。

3.渲染原理

1. 把模板编译成render函数, 如果模板是template或者html 使用parseHtml方法生成ast语法树,
2. 使用正则对html文件进行切割,按照一定的规则拼凑成我们想要的ast语法树 , 
3. 使用ast语法树编译成生成虚拟dom

2.使用with函数将虚拟dom变成render函数字符串, 使用Function将render变成一个匿名函数,
使用vue原型上的_render方法将_c之类的变成虚拟节点。

3.进行渲染部份update方法包裹render,取实列上_vnode 进行保存 判断上一次有没有_vnode, 
使用vm._vnode保存当前传入的虚拟节点。 如果上一次没有_vnode,那么说明是第一次渲染,
vm.$el 获取到转后的html 真实dom 。
如果上一次有_vnode那么说明需要进行比较

4.diff算法

1.在子元素比较之前可以做一些简单得虚拟节点比较
	1.1.如果两个虚拟节点得标签不一致 直接替换即可
	1.2.标签一样但是是两个文本元素 文本元素tag是undefined 直接替换即可
	1.3.元素相同,复用老节点,并且更新属性,用老的属性和新的虚拟节点进行比对更新
	
2.更新子节点
	2.1.老的有儿子 新的也有儿子 diff算法
	2.2.老的有儿子 新的没 删除老的
	2.3.新的有儿子 老的没 直接增加
	
3.diff算法
 要点:1.双指针 2.对常用操作的几种优化 3.无序排列
 
 3.1.双指针指的是 新老节点都有指向自己开始与结束节点的指针,通过不同操作判断节点怎么移动
 
 3.2. 前端中比较常见的操作有 像尾部插入 头部插入 头移动到尾部 尾部移动头部,正序和反序
 
 	(如果处理过的节点自动略过)
	可能节点从前往后移动 发现是空的 那就将老节点的开始节点移动到下一个 
	可能节点从后往前移动 发现是空的 那就将老节点的结束节点移动到上一个
	
	1) 向后插入的操作
	判断头与头是否相同,相同即将新老节点传入patch方法中再走一遍方法,
	新老节点的头指针都向后移动一位
	
	2)向前插入
	判断尾和尾是否相同,相同调用patch传入新老节点,
	新老节点的尾指针都向前移动一位

	3)老的头部与新的尾部相同时
	调用patch方法,将老的头部插入到老的尾指针的下一个节点前面,
	老节点尾指针向后移动一位,新节点尾指针向前移动一位

	4) 老尾和新头比相同时
	调用patch方法,将老的尾节点插入到老的头节点的前面,
	老节点尾指针向前移动一位,新节点头指针向后移动一位

3.3.无序排列 也是乱序排列
	有写专门的解析 可以去我其它文章看

4.最后处理 
	4.1新的比老的多,在老节点最后插入新节点
	
	4.2.老的比新的多,删除老节点多余部分
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值