vue源码学习

136 阅读1分钟

环境配置

  1. clone vue在github上的地址到本地,github.com/vuejs/vue
  2. 安装rollup:npm install -g rollup
  3. 配置命令:npm run dev 中加--sourcemap 以方便查看源码

术语解释

  • runtime:仅包含运行时,不包含编译器
  • common:vue.common.js, cjs规范,用于webpack1.
  • esm: es模块,用于webpack2+
  • umd: 兼容cjs和amd,用于浏览器,也就是我们平时引的vue.js(携带编译器,可以解析template)

new vue步骤

const app=newVue({el:'#app'template:'<div>template</div>'render(h){return h('div','render')}data:{foo:foo}}
  1. 初始化render函数,即将template转化成虚拟dom。el,render和template同时存在的情况下, render>template>el,即保证render函数存在。

  2. 扩展$mount,挂载:将vdom转化成dom

  3. 安装web平台补丁函数patch(用于初始化和更新时使用)

  4. src/core/index.js   初始化全局api

  5. instance/index   定义实例的属性和方法i

  • intMixin 创建vue构造函数,实现_init
  • stateMinxin datadata watch
  • eventMinxin onon off $emit
  • lifecycleMinxin _update,destorydestory forceUpdate
  • renderMinxin   render函数 $nexttick

6.init方法里的实现

  •  initLifecycle(vm)   :$parent,$root,$children
  • initEvents(vm) : 事件监听

  • initRender(vm): slot,createElemment,c,slot,createElemment,_c,attrs,$listtener

  • callHook(vm, 'beforeCreate')  beforeCreate钩子

  • initInjections(vm) // 注入祖辈传入的数据

  • initState(vm) 初始化状态:data.props,method,computed,watch

  • initProvide(vm) //向后代传输数据

  • callHook(vm, 'created') created 钩子

  • $mount()=>mountComponent=>updateComponent()=>render()=>update()=>_patch

数据响应式(initState)

  • 响应式执行顺序:props,methods,data,computed,watch ,后边的不能跟前边的重名
  • observe 递归遍历每个对象,对key做拦截,创建之后会有个__ob__属性
  • observe构造函数:
  1. 创建大管家childob.dep,和对象是一一对应的。监听对象动态删除,增加属性,负责通知,如果存在__ob__就代表已经做过响应
  2. 判断类型做响应式:=>defineReactive:创建小管家dep,和对象的值是一一对应的,变化的时候通知更新。
  • 依赖收集:defineProperty=>get方法

  • 通知更新:defineProperty=>set方法

  • watch和dep之间建立双向绑定关系,多对多。

    这个实例有几个ob?dep?watcher:221
    const app=new vue({
     el:'app',
    data:{
     obj:{
        foo:'foooo'
      }
    }})
    
  • 一个组件一个watcher

  • 一个对象一个observer

  • 一个key一个dep

数组的响应式

  • 重写可以变更数组的七个方法:[push,pop,shift,unshift,splice,sort,reverse]:调用原始实现,创建ob,添加dep通知。