Vue 2.6源码学习(01)-new Vue进行了哪些操作

148 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

1.vue源码的代码结构

git仓库地址:github.com/vuejs/vue.g… "version": "2.6.14",

image.png
  • packages 一些写好的包 (vue源码中包含了weex)
  • scripts 所有打包的脚本都放在这里
  • src 源代码目录
    • compiler专门用作模板编译的
    • core vue2的核心代码
    • platform
    • server 服务端渲染相关的
    • sfc 解析单文件组件的
    • shared 就是模块之间的共享属性和方法

2.new Vue进行了哪些操作

参照官网的生命周期图来看流程 image.png

2.1入口文件src\core\instance\index.js

import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'

function Vue(options) {
  this._init(options)
}

initMixin(Vue) // Vue.prototype._init
stateMixin(Vue) //  Vue.prototype.$set   Vue.prototype.$delete   Vue.prototype.$watch
eventsMixin(Vue) //  Vue.prototype.$on  Vue.prototype.$once Vue.prototype.$off  Vue.prototype.$emit 
lifecycleMixin(Vue) // Vue.prototype._update  Vue.prototype.$forceUpdate   Vue.prototype.$destroy
renderMixin(Vue); //  Vue.prototype.$nextTick  Vue.prototype._render

2.2在init文件中,给Vue对象prototype上增加了_init方法,

image.png

// merge options,通过mergeOptions方法合并
    if (options && options._isComponent) {
      // optimize internal component instantiation
      // since dynamic options merging is pretty slow, and none of the
      // internal component options needs special treatment.
      initInternalComponent(vm, options) // 初始化组件内部的属性
    } else {
      // Vue.options   {beforeCreate:function}  
      vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor),
        options || {},
        vm
      )
    }

2.3初始化一些方法和数据响应式处理

    vm._self = vm
    initLifecycle(vm) // 组件的父子关系 $parent $children
    initEvents(vm)  // 初始化的是$on $off $emit  
    initRender(vm) 
    callHook(vm, 'beforeCreate')
    initInjections(vm) // resolve injections before data/props  inject方法
    initState(vm) // 响应式数据处理
    initProvide(vm) // resolve provide after data/props  provide方法
    callHook(vm, 'created')

2.4 callHook方法的内部处理

路径:src\core\instance\lifecycle.js

// 通过名字找到对应的钩子让其执行
export function callHook (vm: Component, hook: string) {
  // #7573 disable dep collection when invoking lifecycle hooks
  pushTarget()
  const handlers = vm.$options[hook]
  const info = `${hook} hook`
  if (handlers) {
    for (let i = 0, j = handlers.length; i < j; i++) {
      invokeWithErrorHandling(handlers[i], vm, null, vm, info)
    }
  }
  if (vm._hasHookEvent) {
    vm.$emit('hook:' + hook)
  }
  popTarget()
}

2.5 init方法中初始化props,data,computed,watch和observe方法监听数据

export function initState (vm: Component) {
  vm._watchers = []
  const opts = vm.$options
  if (opts.props) initProps(vm, opts.props)
  if (opts.methods) initMethods(vm, opts.methods)
  if (opts.data) {
    initData(vm)
  } else { // 
    observe(vm._data = {}, true /* asRootData */)
  }
  if (opts.computed) initComputed(vm, opts.computed)
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }
}

小结

先简单介绍初始化流程,后面再介绍初始化的一些具体实现

  • initProps
  • initMethods
  • initData
  • initComputed
  • observe
  • initWatch