vue2.0源码解析(上)

vue项目地址:https://github.com/vuejs/vue
当前版本号:2.6.11

一、vue初始化

1、基本目录结构:

WeChat640327ff8c41378361241abdd4c63a5a.png

核心代码目录结构:
WeChatc5510a06b4d2d69b49f0c5345cfd4d1a.png

2、安装依赖以及添加配置
安装依赖: npm i
安装phantom.js时即可终止
安装rollup: npm i -g rollup
修改dev脚本,添加sourcemap,package.json
"dev": "rollup -w -c scripts/config.js --sourcemap --environment TARGET:web- full-dev",
运行开发命令: npm run dev,(加上sourcemap是为了能产生映射文件,能浏览器中进行断点调试)
命令跑起来之后,即可以关闭命令,找到dist目录下会发现vue.js和vue.js.map(映射文件)
在examples/test目录下创建01.init.html
引入前面创建的vue.js,samples/commits/index.html

3、源码初始化分析:
找到package.json文件,找到script对象,可以看到不同的打包方式。
WeChatc37173f866515317285698cee5fcb618.png

rollup打包前端js项目用的比较多,webpack打包前端app项目用的比较多。
WeChatca0f7d986567415488ce0b380dd5f78c.png

提示:平时我们用vue-cli的vue版本是是运行时版本,不带编译器。意味着我们我在new vue里不能使用template模板。使用会报错,只能使用render进行渲染。而html里的new Vue所使用的版本是包含编译器的,所以可以再js中使template模板。
WeChat2bce9ce62383d4baeca9ba1960e8c769.png

根据文件代码提示找到config.js文件
dev脚本中 -c scripts/config.js 指明配置文件所在
参数 TARGET:web-full-dev 指明输出文件配置项,line:123
WeChatad97064230075a8003175864c077ff40.png

使用command+鼠标点击resolve,可以看到aliases数组,然后点击aliases,就可以看到vue路径
WeChate53a1aa5546cdec89b3b9cc8443b4fc0.png

WeChat54fa32ebf30317801a72a9b72ccc1cdc.png

至此,我们知道了vue入口文件。
entry-runtime-with-compiler.js做了什么事:
1、拓展 mount: ![WeChat584bf4a3e2f31cac1b5163a8b6c847a4.png](https://upload-images.jianshu.io/upload_images/21883160-d12a83611b3b49e2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2、判断用户渲染方式的写法: ![WeChat35e6c9183faf61c7561e8a671605eb14.png](https://upload-images.jianshu.io/upload_images/21883160-2e356bbd1fafa64f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 先判断render,再判断template,最后判el元素,所以反应了render优先级最高。 3、如果有模板,就编译它,最终目标是render ![WeChat4e577821894bcfe6f6327f2d836040b2.png](https://upload-images.jianshu.io/upload_images/21883160-b1d34fc9b600c085.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![WeChat9dcc4aa946d5f1a9dc0121d786934400.png](https://upload-images.jianshu.io/upload_images/21883160-3ed115f8364f5b9b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 接着我们根据Vue的引入找到src/platforms/web/runtime文件。 src/platforms/web/runtime文件做的事情包括: 1、安装平台特有补丁函数:做初始化和更新的。 2、实现mount: 初始化挂载
WeChat3ae79f6aa2516f5d73fc7d8e2c59d9be.png

接着我们继续找到vue的引入文件的地方:
src/core/index.js做的事情包括:
1、初始化全局api:包括Vue.use等api。
WeChataca872e0bd6b69156f9717cedd6e8f12.png

继续寻根找到Vue:
找到src/core/instance/index.js文件,至此就能看到Vue的构造方法。
WeChat745c38eb04e36e97cf03a83999954bec.png

1、Vue的构造函数主要是进行了初始化。
那么 new Vue的时候都做了什么初始化。
WeChata221c90f248ce1ab1b8a545203794e1d.png

WeChatb6def94e931b1ce2db3037d32e026442.png

WeChat3269d792afafeea184c8f7db92679307.png

二、响应式

1、找到initState()函数,这是初始化响应式的入口。

WeChat85e2b5c544266f5d441aa121d3f19712.png

2、initstate()函数做了三件事:如下图。
WeChat1ec4cb479fe6855582395fa1d39b6935.png

3、进入initData()函数。
WeChat6b9134bfb3cdaa532a436432f863433d.png

第一步检查是否有命名冲突,第二步,进行递归响应式处理。
4、进入到observe函数。
WeChat576155b1027e8425ef798ed8e5f4cb21.png

第一步获取ob实例,如果没有则进行响应式的添加。
5、进入到Observer类,进行obj和array的区分。
WeChataa17b7b16d11f9a64b166017b2fef271.png

obj 的响应式
6、我们先看obj,进入到walk函数中。
WeChate98f54534657350ef6aa026e4c8e66af.png

对对象的key进行遍历,进入到deineReactive会发现重要的函数Object.defineProperty()。
7、进入defineReactive函数
WeChat7d3dbd76cab1f89a529c5ca461ede3f7.png

按照正常的方式,是一个组件一个watcher,但是如果用户手动添加了watcher,则dep和watcher是多对多的关系,则dep和whatcher进行相互依赖的相互添加。这样才能实现通知更新。
8、点击进入到dep.depend()可以查看到在相互添加引用。
WeChat9fc7b38ec9bbcf1a0c642151f3da19d7.png

array的响应式:
array的响应的核心思想就是将七个会改变原始数组的方法进行覆盖。
找到src/core/observe/array.js文件,做的事情入下图备注:
WeChatd8dd4cab82788b37048ead4595db9e68.png

WeChat8cc60c53d096c70e45441b6fc8a731c1.png

最后覆盖是分ie浏览器和其他浏览器,ie浏览器需要遍历进行覆盖。
image.png

你可能感兴趣的:(vue2.0源码解析(上))