美文网首页
Vue源码01-基础流程分析

Vue源码01-基础流程分析

作者: 熊少年 | 来源:发表于2020-05-21 17:54 被阅读0次
    从毕业到现在也写的有两年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-基础流程分析

          本文链接:https://www.haomeiwen.com/subject/adktahtx.html