Vue2.0原理-模板解析

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

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

入口

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

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 方法又做了什么呢?

...
// 各种初始化开始
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 方法是怎么处理模板的。

  • 判断 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 模板编译原理

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

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

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 库进行字符串模板解析。

posted on 2018-06-13 14:57  smallcoder  阅读(589)  评论(0编辑  收藏  举报

导航