今天开始打算用3个月的时间读一些源码,先从MVVM的vue开始吧。
vue是一个非常不错的前端框架,不仅体积小,性能高,而且学习曲线非常平缓,很容易上手。官方文档也很详解,配套的构建工具很完事。还有很多第三方的组件和组件库,可以让开发者更高效的工作。
源码是vue2.4.0版本。
项目结构
在看源码之前先分析下项目结构,对项目有一个比较全面的了解。
vue-dev项目结构
├── build --------------------------------- 构建相关文件
├── dist ---------------------------------- 生成文件的输出目录
├── examples ------------------------------ 一些vue使用的例子
├── flow ---------------------------------- flow(Flow is a static type checker for your JavaScript code.)类型声明
├── package.json -------------------------- 依赖管理
├── test ---------------------------------- 测试文件
├── src ----------------------------------- 源码
│ ├── compiler -------------------------- 编译器代码,template-->render function
│ │ ├── parser ------------------------ 模板字符串转-->抽象语法树
│ │ ├── codegen ----------------------- 抽象语法树(AST)-->render function
│ │ ├── optimizer.js ------------------ 分析静态树,优化vdom渲染
│ ├── core ------------------------------ 核心代码
│ │ ├── observer ---------------------- 双向绑定,数据观察的代码
│ │ ├── vdom -------------------------- VNode对象&patch方法的代码
│ │ ├── instance ---------------------- Vue构造函数相关的代码
│ │ ├── global-api -------------------- Vue构造函数挂载全局方法(静态方法)或属性的代码
│ │ ├── components -------------------- 通用组件
│ ├── server ---------------------------- SSR(server-side rendering)的代码
│ ├── platforms ------------------------- 平台相关代码
│ ├── sfc ------------------------------- 对单文件组件进行解析
│ ├── shared ---------------------------- 通用代码(util之类)
vue的初始化
了解了大体的目录结构之后,就从package.json开始看起了。在package.json文件里我们发现在执行npm run dev的时候,执行的下面这个脚本,也就是Target是web-full-dev
"scripts": {
"dev": "rollup -w -c build/config.js --environment TARGET:web-full-dev",
...
}
之后去build/config.js里去看看 web-full-dev是什么
'web-full-dev': {
entry: resolve('web/entry-runtime-with-compiler.js'),
dest: resolve('dist/vue.js'),
format: 'umd',
env: 'development',
alias: { he: './entity-decoder' },
banner
}
我们看到这个的入口文件是entry-runtime-with-compiler.js。进入这个文件,它引用了/src/platform/runtime/index—>/src/core/index—>/src/core/instance/index来进行实例化vue。
instance/index.js也就是vue初始化的核心代码了。
//初始化入口
initMixin(Vue)
//数据绑定,$watch方法
stateMixin(Vue)
//事件方法,比如$on,$off,$emit
eventsMixin(Vue)
//生命周期方法
lifecycleMixin(Vue)
//渲染方法,用来生成render function 和 VNode
renderMixin(Vue)
initMixin方法
首选来具体看一下initMixin里做了什么
- initLifecycle — 定义$parent, $root, $children, $refs, _watch,
_inactive, _directInactive, _isMounted, _isDestroyed, _isBeingDestroyed给vue实例 - initEvents — 创建_events事件管理对象,$options._parentListeners监听父组件listener
- initRender –创建_vnode,_staticTrees,$slots,$scopedSlots,$createElement给vue实例
- callHook(vm, ‘beforeCreate’)–执行beforeCreate的钩子方法
initState–
initProps--绑定props initMethods--绑定方法 initData-通过observe进行数据绑定, 给每一个data的属性加上getter,setter.
- callHook(vm, ‘created’)–执行created的钩子方法
- vm.$mount(vm.$options.el) — 通过el or template or render function 渲染dom
stateMixin方法
数据绑定 将$watch,$data,$props,$set,$delete加在Vue.prototype上
eventsMixin方法
初始化事件方法,定义$on,$off,$emit,$once到Vue.prototype上
lifecycleMixin方法
生命周期方法,定义_update,$forceUpdate,$destroy到Vue.prototype上
renderMixin方法
渲染方法,用来生成render function 和 VNode
有不足之处请指正,欢迎一起交流学习。
轮子工厂–一个分享优秀的vue,angular组件的网站