下面這段代碼,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 }
// 模板也分爲多種 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.0種,模板的解析是經過 createDocumentFragment
對dom進行代理實現的,到了2.0時代,考慮到服務端渲染,採用了jquery做者開發的 html-parse
庫進行字符串模板解析。app