(四)Vue-渲染过程

2022-02-28  本文已影响0人  JerrySi

Vue 的不同构建版本

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

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

基于Vue 2.6版本

入口

// 1. el 不能是 body 或者 html 
if (el === document.body || el === document.documentElement) {   
      process.env.NODE_ENV !== 'production' && warn( `Do not mount Vue to 
           <html> or <body> - 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
// 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
  1. src/core/index.js 中引用了 './instance/index'
  2. src/core/instance/index.js
// 此处不用 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
  1. src/platforms/web/runtime/index.js
  1. src/core/index.js
  1. src/core/instance/index.js

首次渲染过程

  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件事:

Demo

上一篇下一篇

猜你喜欢

热点阅读