一、初始化
源码目录
1.new Vue()
当我们new Vue({el:'#app',data:{}}) 时候,这是就要找到Vue的构造函数 该文件的路径为src\core\instance\index.js Vue的构造函数 判断环境并且 立即调用this._init()方法,并把参数传入。 function Vue (options) { 判断是否为生产环境并且 检查vue是否在this的prototype的原型上 // 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) 定义$data,props,set,delete,watch,并且$data和$props是只读属性。 stateMixin(Vue) 初始化事件中心 eventsMixin(Vue) 初始化生命周期 lifecycleMixin(Vue) 初始化渲染函数 renderMixin(Vue) export default Vue
Vue
就是一个Function实现的类,使用必须是new实例,然后调用this._init
方法
构造函数下方执行了很多方法(***MIixin(Vue)
),这些方法的作用就是给Vue
的prototype上面添加一些方法,这些方法是按照功能去定义的,分别在多个模块去实现。
2.this._init()
的过程
this._init(options)
该方法是在initMixin(Vue)
里面实现的。- 路径
src\core\instance\init.js
Vue: Class<Component> 指定传入参数为class类 export function initMixin (Vue: Class<Component>) { 在Vue的原型上面添加_init()方法 负责vue的初始化过程。 Vue.prototype._init = function (options?: Object) { 获取vue的实例 const vm: Component = this 每个vue上面都有一个uid 让vueuid自增 保证vue的唯一性 vm._uid = uid++ vue实例不应该是一个响应式的,做个标记 vm._isVue = true ***************************************************************************** if (options && options._isComponent) { /** * 如果是子组件初始化时走这里,这里只做了一些性能优化 * 将组件配置对象上的一些深层次属性放到 vm.$options 选项中,以提高代码的执行效率 */ initInternalComponent(vm, options) } else { vm.$options = mergeOptions( resolveConstructorOptions(vm.constructor), options || {}, vm ) } /* istanbul ignore else */ if (process.env.NODE_ENV !== 'production') { initProxy(vm) } else { vm._renderProxy = vm } // expose real self vm._self = vm 组件关系初始化 initLifecycle(vm) 初始化自定义事件 initEvents(vm) 初始化插槽 initRender(vm) 调用 beforeCreate 的生命周期 callHook(vm, 'beforeCreate') provide和reject传值 initInjections(vm) // resolve injections before data/props 数据初始化 响应式原理的核心,处理 props methods computed data watch 等 initState(vm) provide和reject传值 initProvide(vm) // resolve provide after data/props 调用 created 的生命周期 callHook(vm, 'created') /* istanbul ignore if */ // if (process.env.NODE_ENV !== 'production' && config.performance && mark) { // vm._name = formatComponentName(vm, false) // mark(endTag) // measure(`vue ${vm._name} init`, startTag, endTag) // } 判断数据中有没有el,如果有,自动执行$mount 没有的话,就要手动去挂载。 if (vm.$options.el) { vm.$mount(vm.$options.el) } } }
3.响应式原理initState(vm)
- initState在
import { initState } from './state'
- 同级目录下找到state.js
export function initState (vm: Component) { vm._watchers = [] const opts = vm.$options 处理props对象 为每一个props对象上面设置响应式 if (opts.props) initProps(vm, opts.props) 处理methods if (opts.methods) initMethods(vm, opts.methods) 初始化data, if (opts.data) { initData(vm) } else { observe(vm._data = {}, true /* asRootData */) } 处理conputed if (opts.computed) initComputed(vm, opts.computed) 处理watch if (opts.watch && opts.watch !== nativeWatch) { initWatch(vm, opts.watch) } }