vue源码解析

一、初始化

1.new Vue()

当咱们new Vue({el:'#app',data:{}}) 时候,这是就要找到Vue的构造函数该文件的门路为src\core\instance\index.jsVue的构造函数  判断环境并且 立刻调用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)  }}