Vue源码01-基础流程分析

从毕业到现在也写的有两年Vue了,本着高深追求就去学习了Vue的源码,就把学习过程中的理解记录下来,这将是一个系列的文章,一次不可能写完,会不断更新,后续还会有vuex和vue-router系列
先从Vue的目录说起
image.png
  • scripts目录里面包含我们打包所需要的脚本
  • src里面包含的就是vue的源码目录了
    • compiler模版编辑器生成 render,ast,staticRenderFns
    • core vue的主要代码目录包含生命周期,静态方法,原型方法,属性,vdom,observe等一系列
    • platform 打包的入口 也是我们阅读源码的入口(这里只讲web)
    • server 服务端渲染相关
    • sfc 解析单文件组件
    • shared 项目包含的公共方法和常量
这里先讲解vue的加载流程

每行代码基本都有注释,请细看注释

分析packge.json
"build": "node scripts/build.js"  //告诉我们打包的入口是scripts/build.js
分析打包
 // build.js
 let builds = require('./config').getAllBuilds()   // 引入config
.....
build(builds)   // 打包通过分析config.js
// config.js,这里选择这一个  也是我们最常用的vue.min.js
  'web-full-prod': {    
    entry: resolve('web/entry-runtime-with-compiler.js'), // 将从这个目录读起
    dest: resolve('dist/vue.min.js'),
    format: 'umd',
    env: 'production',
    alias: { he: './entity-decoder' },
    banner
  },
分析web/entry-runtime-with-compiler.js

将会简化这里的代码后续慢慢补充

// web/entry-runtime-with-compiler.js 
const idToTemplate = cached(id => {   //将template缓存起来,避免重复解析
  const el = query(id)
  return el && el.innerHTML
})
const mount = Vue.prototype.$mount  // 来自runtime/index.js 运行mountComponent
Vue.prototype.$mount =function(){
 // 1解析template
 // 2生成options.render
}  // 挂载$mount 这里需要分析清楚这两个$mount
// runtime/index.js 
Vue.prototype.__patch__ = inBrowser ? patch : noop //添加patch
Vue.prototype.$mount= function(){
  // 运行mountComponent dom挂载已经beforeMount,beforeUpdate,mounted挂载
 return mountComponent(this, el, hydrating)
}

从上面的代码里面我们知道Vue来自core/index.js

分析core/index.js
initGlobalAPI(Vue) // 这里会给Vue挂载静态方法 use,mixin,extend,component,directive,filter
分析core/instance/index.js

到这里才见到Vue的构造函数,详情参考注释,每句都有注释

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)  // 运行_init 给vue进一步初始化,已经注册beforeCreate,created
}
// 在Vue的原型上面挂在相关方法 
initMixin(Vue)  // 挂载_init
stateMixin(Vue) // 挂载$data,$props,$set,$delete,$watch
eventsMixin(Vue) // $on,$once,$off,$emit
lifecycleMixin(Vue)// _update ,$forceUpdate,$destroy
renderMixin(Vue) //$nextTick,_render
     // init.js分析重要部分
    // 这里对options初始化**mergeOptions**后续会讲
    vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor),
        options || {},
        vm
     )
    // 深入初始化
    initLifecycle(vm) // 初始化生命周期相关属性
    initEvents(vm) // 初始化事件相关属性
    initRender(vm) // 初始化render所需要的方法  vm._c  vm.$createElement
    callHook(vm, 'beforeCreate')  // 调用beforeCreate生命周期钩子
    initInjections(vm) // resolve injections before data/props
    initState(vm) // 初始化state
    initProvide(vm) // resolve provide after data/props
    callHook(vm, 'created') // 调用created生命周期钩子
    // 挂载
    if (vm.$options.el) {
      vm.$mount(vm.$options.el) // 这里调用的是web/entry-runtime-with-compiler.js 里面的mount
    }

这里有几个面试题
1 vue的provide 和 inject注册顺序以及怎么注册?
2 vue在beforeCreate之前干了什么?created之前做了什么?

通过上面的分析我们已经对Vue有了一个大概的认识能回答从new Vue()到mount做了哪一些事?后续我们会继续分析这些‘事’都是什么

小节Vue挂载流程:

  • Vue.prototype.patch 挂载patch方法
  • Vue.prototype.$mount 运行mountComponent
  • Vue.prototype.$mount 解析render
  • initGlobalAPI(Vue) 给Vue挂载静态方
  • 在Vue的原型上面挂在相关方法和属性
  • 调用_init()
  • 在initState里面干了什么?下章节将
  • 调用 3中的$mount()对render进行判断并且生成对应的render
  • 运行mountComponent

你可能感兴趣的:(Vue源码01-基础流程分析)