## 认识Flow
Flow是facebook出品的Javascript静态类型检查工具,Vue.js的源码利用了Flow做了静态类型检查。
### 为什么用?
Javascript是动态类型语言,灵活性强,但过于灵活的副作用是很容易写出非常隐蔽的隐患代码,在编译器甚至看上去都不会报错,但是在运行阶段就可能出现各种奇怪的bug
类型检查是当前动态类型语言的发展趋势,就是在编译期禁止发现(由类型错误引起的)bug,又不影响代码运行。使编写的Javascript具有和编写java等强类型语言相近的体验。
项目越复杂就越需要工具来保证项目的维护性和增强代码的可读性。
Vue 2.0重构时,在ES2015基础上,**除了ESLint保证代码风格,也引入Flow做静态类型检查**。
## 源码目录设计
![](https://box.kancloud.cn/ab67af35f222ca545f145cef2fc0dd81_339x181.png)
* compiler:编译相关代码,包括把模板解析成AST语法树,AST语法优化,代码生成等功能。
编译的工作可以在构建时做(webpack,vue-loder等),也可以在运行时做,编译时一项耗性能的工作。
* core :vue的核心代码,包括内置组件,全局API封装,Vue实例化,观察者,虚拟DOM,工具函数等
* platform vue是一个跨平台的mvvm框架,可以跑在web上,也可以配合weex跑在native客户端上。
* server:vue2.0支持了服务端渲染,素银服务端渲染相关逻辑都在这个目录。这部分代码是跑在服务端的node.js。服务端渲染:把组件渲染为服务端的HTML字符串,将他们直接发送到浏览器,最后将静态标记”混合“为客户端上完全交互的应用程序
* sfc:通常vue都会借助webpack构建,然后通过.vue单文件来编写组件,这个目录的代码逻辑会把.vue文件内容解析成一个Javascript的对象。
* shared 共享
## vue.js源码构建
Vue.js源码是基于Rollup构建的,构建的相关配置都在scripts目录下。
Vue两个版本:
Runtime Only:**借助webpack和vue-loader**把我们vue文件编译成JavaScript,(浏览器不认识vue文件),把template模板编译成render函数,编译后是一个render函数的版本,所以Runtime Only是不带编译的,**编译是在离线的时候做**。因为是**在编译阶段做的**,所以它只包含运行时的Vue.js,因此代码体积也会更轻量。
推荐:体积小
Runtime+Compiler:可以不对代码做预编译,也可以用vue单文件方式。我们如果没有对代码做预编译,但又使用了Vue的template属性,并传入一个字符串,则需要在客户端编译模板。(是在**运行的时候**做的)。
## 从入口开始
来分析 Runtime + Compiler 构建出来的 Vue.js,它的入口是`src/platforms/web/entry-runtime-with-compiler.js`:
当我们的代码执行`import Vue from 'vue'`的时候,就是从这个入口执行代码来初始化 Vue,它实际上就是一个用 Function 实现的类,我们只能通过`new Vue`去实例化它。
为何 Vue 不用 ES6 的 Class 去实现呢?
我们往后看这里有很多`xxxMixin`的函数调用,并把`Vue`当参数传入,它们的功能都是给 Vue 的 prototype 上扩展一些方法(这里具体的细节会在之后的文章介绍,这里不展开),Vue 按功能把这些扩展分散到多个模块中去实现,而不是在一个模块里实现所有,这种方式是用 Class 难以实现的。这么做的好处是非常方便代码的维护和管理,这种编程技巧也非常值得我们去学习。
*****
定义`--patch--`,`$mount`方法
Vue是一个function,必须实例化,new Vue
不使用class的原因:
**每一个mixin就是往Vue的原型上混入一些原型上的方法,用ES6实现这个效果比较难写,用ES5实际上可以往Vue原型上挂载很多方法,并可以放在不同文件下。方便代码管理**
initMixin:往Vue.prototype上挂了_init方法
stateMixin:往Vue.prototype上挂载一些方法`$set,$delete`,
eventsMixin
lifecycleMixin:
renderMixin:
**Vue本身是一个函数,可以理解为一个类,这个类上面挂了很多原型方法,通过mixin等混入。**
初始化**全局API**:往Vue上挂载一些静态属性。
Vue.set,Vue.delete,Vue.nextTick,Vue.options
Vue.options:可以合并一些方法,比如**component,directive,filter**(全局方法)
**内置组件:keep-alive,通过Vue.extend方法扩展的**。
Vue.use:
**在import Vue的过程中:
初始化过程中,完成了全局方法的定义,之后才可以在代码中使用,在import Vue中完成的。**
Vue初始化的两个步骤:
**1. 找到Vue的定义,并通过mixin方法,挂载了很多原型方法。
2. 通过initGlobalAPI,给Vue挂载了很多静态方法。**
静态方法:为类所有,可以通过类来调用。
**Vue.use,Vue.set,Vue.componets,Vue.directives,vue.filters,Vue.defineReative,Vue.extend,Vue.mergeOptions,vue.version,Vue.config**
- 空白目录
- 双樾
- JS基础知识
- JS-WEB-API
- 开发环境
- 运行环境
- ES6
- 原型
- 异步
- 虚拟dom
- mvvm
- 组件化和React
- hybrid
- 其他
- 补充
- 技巧
- 快乐动起来呀
- css
- 掘金小册子
- js基础知识
- ES6知识点
- JS异步
- JS进阶知识
- 思考题
- DevTools Tips
- 浏览器基础知识
- 浏览器缓存机制0
- 浏览器渲染原理
- 安全防范知识点0
- 从V8中看JS性能优化0
- 性能优化琐碎事
- Webpack性能优化0
- 实现小型打包工具0
- React和Vue
- Vue生命周期
- vue基础知识点
- Vue响应式
- vue高级
- React基础
- Vue.js技术解密
- 准备工作
- 数据驱动
- new Vue()
- vue实例挂载
- 组件化
- 深入响应式原理
- 编译
- 扩展
- Vue Router
- Vuex