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

相關文章
相關標籤/搜索