Vue2.0原理-模板解析

下面这段代码,vue内部作了什么操做?我去源码里面找找看html

new Vue({
    el: '#app'
})

入口

vue 的入口文件在 src/core/instance/index.js, 里面一进来就执行了不少初始化的操做。vue

import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
import { warn } from '../util/index'

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)

export default Vue

进入 initMixin 方法看看,这个方法内部只作了一件事,定义 Vue.prototype._init , 这个 _init 方法又作了什么呢?jquery

...
// 各类初始化开始
initProxy(vm)
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
// 各类初始化完毕
...
// 解析模板
if (vm.$options.el) {
  vm.$mount(vm.$options.el)
}

解析

进入 src/platforms/web/entry-runtime-with-compiler.js 文件,看看 $mount 方法是怎么处理模板的。git

  • 判断 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
  }
  • 若是没有render函数,则开始解析模板
// 模板也分为多种
1,当使用 template 属性时,支持:
    1.1, 字符串模板
    1.2,一个script模板的id
    1.3,一个dom对象

2,当使用 el 属性时,获取对应dom的outerHTML 做为template
  • 调用 src/compiler/index.js 对模板进行AST解析和静态优化,并重建render方法

对于模板解析,这篇文章分析的很详细 Vue 模板编译原理github

  • 在解析完模板以后,调用的是 runtime/index.js 中的 $mount 方法。

$mount 方法调用 src/core/instance/lifecycle.js 中的 mountComponent 方法web

mountComponent() {
    // 1,通过上面的一系列初始化动做,render确定已经有了,若是没有,返回一个节点并警告。
    callHook(vm, 'beforeMount')
    // 2,经过vm._render()方法把模板转化成vNode
    // 3,经过vm._update()更新dom节点
    callHook(vm, 'mounted')
}

和VUE1的区别

在vue1.0种,模板的解析是经过 createDocumentFragment 对dom进行代理实现的,到了2.0时代,考虑到服务端渲染,采用了jquery做者开发的 html-parse 库进行字符串模板解析。app

相关文章
相关标签/搜索