第01章 准备工作
1-01 准备工作
一、vuejs源码并不全是用es6写的。
二、vue技术揭秘:https://ustbhuangyi.github.io/vue-analysis/
1-02 认识flow
一、flow是facebook出品的javascript静态类型检测工具,vue.js的源码利用了flow做了静态资源检查,所以了解flow有助于我们阅读源码。
二、
1、安装flow:https://flow.org/en/docs/install/
(1)npm install --save-dev babel-cli babel-preset-flow
(2)./node_modules/.bin/babel src/ -d lib/
(3)npm install --save-dev flow-bin
(4)npm run flow init
(5)npm run flow
(6).babelrc package.json .flowconfig 配置
三、flow的libdef概念,可以识别第三方库或者是自定义类型,vue.js也是利用了这一特性。
1-03 vue.js源码目录设计
一、src/ compiler:编译相关的代码
template to render function相关逻辑在compiler里。
二、src/ core/ global/ mixin.js等
src/ core/ instance: vue 生命周期
src/ core/ observer 响应式相关
src/ core/ util: 工具、方法
src/ core/ vdom: virtual dom
三、platforms: web、 weex
可以编译出在浏览器运行的框架
四、server:服务端代码
五、通过rollup把上述这些js打包成一个单独的js
1-04 源码构建
一、vue.js源码是基于rollup构建的
二、 gulp、grunt:以业务为基准的。
三、path.resolve是nodejs提供的方法
1-05 从入口开始
一、vue实际上是一个类,类上挂了很多原型方法。
二、vue的util方法不建议外面的库去使用,因为里面的方法不是很稳定。
三、keepAlive是一个内置组件。
四、vue初始化过程:
1、找到vue的定义:instance/ index.js
2、vue是一个class,通过mixin给vue原型挂载很多原型方法。
3、initGlobalAPI给vue挂载很多静态方法。
第02章 数据驱动
2-01 数据驱动
一、数据驱动:视图是由数据驱动生成的。对视图的修改,不会直接操作dom。
二、vm.$mount(options),模板才被编译成视图
2-03 vue实例挂载的实现
一、vue不可以挂载到html或body,会被覆盖,所以用#app
2-04 render
一、被编译生成的render函数使用的方法:vm_.c
手写的render函数使用的:vm.$createElement
var app = new Vue({
el: '#app',
render(createElement) {
return createElement('div', {
attrs: {
id: 'app1'
}
}, this.message);
},
data() {
return {
message: 'hello vue'
}
}
})
2-05 virtual dom
一、虚拟dom的定义:src/ vdom/ vnode.js
二、flow/ vnode.js/ VNodeData能得到vnode数据类型
三、vdom是参考开源库snabbdom的实现
四、vnode只是用来映射到真实dom的渲染,不需要包含操作dom的方法,因此非常轻量和简单。
2-07 update
函数柯里化:假如一个函数只能收一个参数,那么这个函数怎么实现加法呢,因为高阶函数是可以当参数传递和返回值的,所以问题就简化为:写一个只有一个参数的函数,而这个函数返回一个带参数的函数,这样就实现了能写两个参数的函数了(具体参见下边代码)——这就是所谓的柯里化(Currying,以逻辑学家Hsakell Curry命名),也可以理解为一种在处理函数过程中的逻辑思维方式。
第03章 组件化
3-02 createComponent
一、
Sub.prototype = Object.create(Super.prototype);
Sub.prototype.constructor = Sub;
二、data原先只有一个on,installComponentHooks执行之后多了一个hook,
hook中有destroy, init, insert, pepatch
三、componentOptions的children,在插槽的时候会用到
3-03 patch(上)
一、patch的结果返回的是一个dom
二、整个插入过程是先子后父。
三、可用debugger调试源码断点
3-04 patch(下)
一、patch流程:createComponent -> 子组件初始化 -> 子组件render -> 子组件patch
二、activeInstance为当前激活的vm实例;vm.$vnode为组件的占位vnode,vm._node为组件的渲染vnode
三、嵌套
3-06 合并配置(下)
一、外部调用场景下的合并配置是通过mergeOption,并遵循一定的合并策略。
二、组件合并是通过initInternalComponent,它的合并更快。
三、框架、库的设计都是类似,自身定义了默认配置,同事可以在初始化阶段传入配置,然后merge配置,来达到定制化不同需求的目的。