获取vue

项目地址 :https://github.com/vuejs/vue


初始化流程

整体流程

  • new Vue()
    • init()
  • $mount()
    • mountComponent
      • updateComponent()
        • render()
        • update()
      • new Watcher()

WechatIMG10.png
core/index.js
初始化全局api
具体如下:

  1. vue.set = set;
  2. vue.delete = del;
  3. vue.nextTick = nextTick;
  4. initUse(vue) //实现vue.use参数
  5. initMixin(vue)//实现vue.Mixin函数
  6. initExtend(vue)//实现vue.extend函数
  7. initAssetRegister(vue)//注册实现Vue.component/directive/filter

core/instance/init.js
创建组件实例,初始化其数据,属性,事件

  1. initLifecycle(vm) //$parent,$root,$children,$refs
  2. initEvents(vm) //处理父组件传递的事件和回调
  3. initRender(vm) //$slot $scopedSlots _c $createElement
  4. callHook(vm, 'beforeCreate')
  5. initInjections(vm) // 获取注入数据
  6. initState(vm) // 初始化props,methods,data,computed,watch
  7. initProvide(vm) // 提供数据注入
  8. callHook(vm, 'created')

思考一道面试题,谈谈vue的生命周期

  • 概念:组件更新,创建,销毁的过程
  • 用途:生命周期钩子使我们可以在合适的时间做合适的事情
  • 分类列举:
    • 初始化过程:beforeCreate Created beforeMounte Mounted
    • 更新过程:beforeUpdate,Updated
    • 销毁过程:beforeDestory destoryed
  • 应用
    • created时,所有数据准备就绪,适合做数据获取,赋值等操作
    • mounted时,$el已生成,可以获取dom,组件已经挂载,可以访问他们
    • updated时,数值变化已经作用于dom,可以获取dom最新状态
    • destoryed时,组件实例已销毁,适合做定时器等操作

数据响应式

数据响应式是MVVM框架的一大特点,通过某种策略可以感觉数据变化,Vue2.0中利用了JS语言特性Object.defineReactive(),通过定义对象属性的getter/setter拦截对象属性的访问

具体实现是在Vue初始化时,会调用initState,它会初始化data,props等,

整体流程
initState (vm: Component) src\core\instance\state.js
初始化数据,包括props、methods、data、computed和watch

initData核心代码是将data数据响应化

  1. function initData (vm: Component) {
  2. // 执行数据响应化
  3. observe(data, true /* asRootData */)
  4. }

core/observer/index.js
observe方法返回一个Observer实例

core/observer/index.js
Observer对象根据数据类型执行对应的响应化操作 defineReactive定义对象属性的getter/setter,getter负责添加依赖,setter负责通知更新

core/observer/dep.js
Dep负责管理一组Watcher,包括watcher实例的增删及通知更新
WechatIMG11.png

watcher
watcher解析一个表达式并收集依赖,当数值变化时触发回调函数,常用于$watch api和指令
每个组件也会有对应的watcher,数值变化,触发其update函数导致重新渲染

  1. export default class Watcher {
  2. constructor () {}
  3. get () {}
  4. addDep (dep: Dep) {}
  5. update () {}
  6. }

WechatIMG12.png

数组响应化

数组数据变化的侦测跟对象不同,我们操作数组通常使用push、pop、splice等方法,此时没有办法得 知数据变化。所以vue中采取的策略是拦截这些方法并通知dep。

src\core\observer\array.js
为数组原型中的7个可以改变内容的方法定义拦截器

Observer中覆盖数组原型

  1. if (Array.isArray(value)) {
  2. // 替换数组原型
  3. protoAugment(value, arrayMethods) // value.__proto__ = arrayMethods
  4. this.observeArray(value)
  5. }