[Vue源码] Vue中响应式数据的原理

1、vue2.0 响应式数据的原理

概述Object.defineProperty() 递归数据劫持+订阅发布者模式

Vue2.0在初始化数据时,会给data中的属性使用Object.defineProperty重新定义所有属性,当页面取到对应属性时,会进行依赖收集(收集当前组件的watcher)如果属性发生变化会通知相关依赖进行更新操作。
在这里插入图片描述

源码:src/observer/index.js

/**
*   Observer ,抽象了对象的公共部分,之后用这个类来实例化对象。
*	constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法
*  类中添加方法有:def(改变对象的可遍历性)、walk(观察对象) 、observeArray(观察数组)
*/
export class Observer {
   
  value: any;
  dep: Dep;
  vmCount: number; // number of vms that have this object as root $data

  constructor (value: any) {
   
    this.value = value
    // 增加dep属性(处理数组时可以直接调用)
    this.dep = new Dep()
    this.vmCount = 0

    // 将Observer实例绑定到data的__ob__属性上面去,后期如果oberver时直接使用,不需要从新Observer,
	// 处理数组是也可直接获取Observer对象
    // Define a property.
    
    def(value, '__ob__', this) //value是data,'__ob__'为属性名, this是observer实例

	export function def (obj: Object, key: string, val: any, enumerable?: boolean) {
   
	    Object.defineProperty(obj, key, {
   
	      value: val,
	      enumerable: !!enumerable,//是否可遍历
	      writable: true,
	      configurable: true
	    })
	 }


    if (Array.isArray(value)) {
    // 判断数组
    
      if (hasProto) {
   //如果已经更改过原型
      
      	//通过截获原型链来扩充目标对象
        protoAugment(value, arrayMethods)
        
      } else {
   //没有更改过原型,则通过定义隐藏属性来扩充目标对象或数组。 
        copyAugment(value, arrayMethods, arrayKeys)  
      }
      this.observeArray(value)//观察数组
    } else {
   
      // 测试对象
      this.walk(value);//遍历对象,调用defineReactive()使每个属性变为响应式数据  
    }
  }

  /**
   * 遍历对象,调用defineReactive()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值