前言
眨眼间,菜鸡本鸡已经步入职场2年了,在这两年中随着项目的深入接触,在较大的项目中解决bug的过程中会接触到F12只显示vue源码在执行过程中的异常,导致debug难度加大,再碰到这种问题的时候往往就会体会到心有余而力不足的情况,为了在碰到问题的时候能更快的解决问题,在观看了几个博主及源码学习视频之后,决定先从核心模块代码学起,开始自己的菜鸡源码求学之路,写的不好或者哪里有瑕疵欢迎批判改进,谢谢.
源码部分
Vue初始化
从上图中可以发现,Vue其实就是构造函数
通过引用'/src/index.js'文件使得该页面可以调用Vue函数,通过new调用。触发'/src/index.js'文件中Vue函数并在Vue函数中传入一个参数,在Vue事件执行过程中调用'./init'文件中'initMix事件',如下图
触发'initMix事件',在原型上挂在_init初始化事件,给Vue原型添加方法。通过引入文件的方式调用Vue页面元素初始化事件'initState'并传递参数,利于代码切割,如下图(后续初始化data、props、methods、computed、watch等也是运用了代码切割的思想)
触发'initState事件',在该事件中充分运用了代码切割的模式,分别初始化Vue的数据来源(属性、方法、数据、计算属性、数据监察等),在这里先讨论响应式数据相关方法,在获取用户传递的data后,运用三元表达式对data进行类型判断,并触发响应式关键事件'observe'事件,如下图
触发'Observer事件',Vue数据劫持的关键在于递归用户传入的data并利defineReactive函数中的Object.defineProperty的get和set事件进行赋值和修改,在这里数据变动了,函数就会在set中通知数据的更新,使得视图与数据变化同步.
但是用递归去遍历用户传入的任何数据并不是最佳方案,如果用户传入的数据data中存在双重数组并在第二重数组中嵌套了几千几万个数据时,对所有数据的下标进行索引显然对系统性能来说是一个极大的考验,故Vue在defineReactive函数中通过引入'../util/index'中'isObject事件'增加了对用户传入数据类型判断函数,如下图
在Observer函数中使用Array.isArray事件监测到用户传入的数据是否为数组,如果是数组,则调用observerArray函数进行遍历,并将遍历的子元素传入observe函数中.如果是对象,则直接调用defineReactive进行深度监测并实现劫持,如下图
- 思考:为什么Object.defineProperty不能同步对象内元素在视图与数据中的更新?
- 思考:Vue响应式数据在数组中是如何重写方法的?
题外话:小补New实例化及构造函数的基础知识
1、构造函数:用new调用一个函数,任何函数都可以为构造函数.
2、New实例化四步走:
- 函数会创建一个空白对象.
- 函数上下文(this)会指向这个对象.
- 函数内语句执行.
- 函数内自动返回上下文,即使函数内无return语句.