Vue 源码阅读

11.18'24

介绍

Vue.js 是一个可以由简到繁构建 web UI 的 JavaScript 框架。

Github 源码:https://github.com/vuejs/vue

官网:https://vuejs.org

源码

地址:https://github.com/vuejs/vue/tree/dev/src

package.json:项目配置和入口

用 npm 管理的项目,其配置信息都保存在package.json中。

Vue.jsrollup 进行打包,配置文件和脚本放在scripts文件下。

打包后的文件作为入口文件main

package.json

"scripts": {
  "dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev",
  ...
},

web 端开发打包环境为例,查看 scripts/config.js,可以找到入口为 src/platform 下的 web/entry-runtime-with-compiler.js

// Runtime+compiler development build (Browser)
'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
},

src 目录结构

使用 Vue.js 后会发现,主要是实例化 Vue 对象和调用 Vue 上的方法。在阅读源码时就要重点关注 Vue 对象 的定义及其方法的添加。

src             // 源码
|+compiler/     // 编译器,基于 AST 解析 HTML 代码和重新生成
|+core/         // 核心功能,定义了 Vue 对象
|+platforms/    // 入口,按平台添加 web 和 weex 的编译器和运行时等
|+server/       // 服务端渲染
|+sfc/          // single-file component (*.vue) 解析成 sfc 描述对象
`+shared/       // 共享的常量和工具函数

Vue 对象

查看src/platform/web/entry-runtime-with-compiler.js:在 Vue 对象及其原型上添加加载、编译方法后导出。

import Vue from './runtime/index'

Vue.prototype.$mount = function (
...

Vue.compile = compileToFunctions

export default Vue

src/platform/web/runtime/index -> src/core/index.js: Vue 对象最终来自于 src/core/instance/index.js,添加全局方法(Global API)后导出

Vue 对象的定义、内部方法

src/core/instance/index.js:定义 Vue 对象,添加初始化,添加状态、事件、生命周期、渲染等方法。

function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  this._init(options)
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

Vue 对象的全局方法

src/core/index:可以看出全局方法是通过 src/core/global-api/index添加的。

import Vue from './instance/index'
import { initGlobalAPI } from './global-api/index'

...
initGlobalAPI(Vue)
...

export default Vue

global-api目录,对 Vue 对象添加了各类方法。以常用的component为例,src/core/shared/contants.js中配置,global-api/assets.js中定义。

~global-api/
 |-assets.js
 |-extend.js
 |-index.js
 |-mixin.js
 `-use.js

Virtual DOM

src/core/vdom包含了对虚拟 DOM 的相关处理。Vue.js 的虚拟 DOM 更新来自于虚拟 DOM 库 snabbdom: https://github.com/snabbdom/snabbdom

虚拟 DOM 会创建虚拟节点(vnode),通过 DOM API 和实际 DOM 节点交互。通过 patch 方法对比新旧节点实现部分更新以提高效率。

DOM API,即常用的原生 createElment,AppendChild,removeChild 等。

📖