(四)Vue-渲染过程

Vue 的不同构建版本

完整版:同时包含编译器和运行时的版本。
编译器:用来将模板字符串编译成为 JavaScript 渲染函数的代码,体积大、效率低。
运行时:用来创建 Vue 实例、渲染并处理虚拟 DOM 等的代码,体积小(小大约 30%)、效率高。基本上就是除去编译器的代码。

UMD:UMD 版本通用的模块版本,支持多种模块方式。 vue.js 默认文件就是运行时 + 编译器的UMD 版本。
CommonJS(cjs):CommonJS 版本用来配合老的打包工具比如 Browserify 或 webpack 1。
ES Module:从 2.6 开始 Vue 会提供两个 ES Modules (ESM) 构建文件,为现代打包工具提供的版本。

  • ESM 格式被设计为可以被静态分析,所以打包工具可以利用这一点来进行“tree-shaking”并将用不到的代码排除出最终的包。
  • ES6 模块与 CommonJS 模块的差异

基于Vue 2.6版本

入口

  • el 不能是 body 或者 html 标签
  • 如果没有 render,把 template 转换成 render 函数
  • 如果有 render 方法,直接调用 mount 挂载 DOM
// 1. el 不能是 body 或者 html 
if (el === document.body || el === document.documentElement) {   
      process.env.NODE_ENV !== 'production' && warn( `Do not mount Vue to 
            or  - mount to normal elements instead.` )
      return this 
}

const options = this.$options if (!options.render) { 
    // 2. 把 template/el 转换成 render 函数 …… 
}
    
// 3. 调用 mount 方法,挂载 DOM 
return mount.call(this, el, hydrating)

初始化流程

  1. src/platform/web/entry-runtime-with-compiler.js 中引用了 './runtime/index'
  2. src/platform/web/runtime/index.js
  • 设置 Vue.config
  • 设置平台相关的指令和组件
    指令 v-model、v-show
    组件 transition、transition-group
  • 设置平台相关的 patch 方法(打补丁方法,对比新旧的 VNode)
  • 设置 $mount 方法,挂载 DOM
// install platform runtime directives & components extend(Vue.options.directives, platformDirectives) extend(Vue.options.components, platformComponents) 

// install platform patch function 
Vue.prototype.__patch__ = inBrowser ? patch : noop

 // public mount method Vue.prototype.$mount = function ( 
    el?: string | Element, 
    hydrating?: boolean ): Component { 
    el = el && inBrowser ? query(el) : undefined 
    return mountComponent(this, el, hydrating) 
}
  1. src/platform/web/runtime/index.js 中引用了 'core/index'
  2. src/core/index.js
  • 定义了 Vue 的静态方法
  • initGlobalAPI(Vue)
  1. src/core/index.js 中引用了 './instance/index'
  2. src/core/instance/index.js
  • 定义了 Vue 的构造函数
// 此处不用 class 的原因是因为方便,后续给 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') 
    }

    // 调用 _init() 方法 
    this._init(options) 
}

// 注册 vm 的 _init() 方法,初始化 
vm initMixin(Vue) 
// 注册 vm 的 $data/$props/$set/$delete/$watch 
stateMixin(Vue) 
// 初始化事件相关方法 
// $on/$once/$off/$emit 
eventsMixin(Vue) 
// 初始化生命周期相关的混入方法 
// _update/$forceUpdate/$destroy 
lifecycleMixin(Vue) 
// 混入 render 
// $nextTick/_render 
renderMixin(Vue)

导出Vue涉及的四个模块

  1. src/platforms/web/entry-runtime-with-compiler.js
  • web 平台相关的入口
  • 重写了平台相关的 $mount() 方法
  • 注册了 Vue.compile() 方法,传递一个 HTML 字符串返回 render 函数
  1. src/platforms/web/runtime/index.js
  • web 平台相关
  • 注册和平台相关的全局指令:v-model、v-show
  • 注册和平台相关的全局组件: v-transition、v-transition-group
  • 全局方法:
    patch:把虚拟 DOM 转换成真实 DOM
    $mount:挂载方法
  1. src/core/index.js
  • 与平台无关
  • 设置了 Vue 的静态方法,initGlobalAPI(Vue)
  1. src/core/instance/index.js
  • 与平台无关
  • 定义了构造函数,调用了 this._init(options) 方法
  • 给 Vue 中混入了常用的实例成员

首次渲染过程

  1. 实例化Vue对象的时候。会调用this._init()进行一些初始化, 同时会调用vm.$mount函数。

这里的vm.$mount函数 首先调用src/platforms/web/entry-runtime-with-compiler.js 里面重写的$mount() 方法。

  1. 重写的vm.$mount函数: 通过Vue.compile() 方法,返回 render 和 staticRenderFns 函数, 存储在$options里面。 然后调用原始的vm.$mount函数。
  • 这里的render:如果用户定义,返回用户定义的; 否则返回模板生成的。
  • 原始的vm.$mount函数 是src/platforms/web/runtime/index.js 里面定义的
  • src/platforms/web/runtime/index.js里面同时定义了vm.patch方法把虚拟Dom转成真实Dom
  1. 原始的vm.$mount函数:调用 mountComponent方法。
    mountComponent定义在/src/core/instance/lifecycle.js
  2. mountComponent方法主要做了4件事:
  • 触发beforeMount钩子
  • 定义updateComponent方法, 注意这里只是定义, 触发是Watcher触发的。
  • 创建Watcher实例, 把updateComponent方法作为参数传入。
  • 触发mounted钩子
    4.1 updateComponent方法比较重要, 主要做了2件事:
    vm._rander渲染虚拟Dom。
    vm._rander其实就是调用第二步$options中的render方法
    vm._update更新,把虚拟Dom转成真实Dom 。
    vm._update其实就是调用src/platforms/web/runtime/index.js中的定义的vm.__patch__方法, 同时记录vm.$el
    4.2 Watcher构造方法
    会把传入的updateComponent参数赋值给this.getter。
    this.get()方法里面调用this.getter。
    立即调用this.get(), 进而触发渲染。

Demo

你可能感兴趣的:((四)Vue-渲染过程)