下面这段代码,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