VUE源码解析(持续更新)

VUE源码解析(持续更新),第1张

src\core\observer\index.js

export class Observer { } Observer这个类会被附加在每一个可观察对象上
export function defineReactive ( } 利用 Object.defineProperty 函数作用于对象属性的值,进行取值和赋值 *** 作时的拦截和处理

数组对象中的每一个key设置dep,为什么在Observer里声明dep?(给每个对象加一个dep呢)

1.obeject里面有新增或者删除属性
2.array中有变更方法
都需要dep去通知watcher去检测变化 ,然后做更新(diff算法),只更新修改的部分
(会触发setter方法,告诉watcher有依赖变化,watcher收到信息,重新渲染dom,实现页面数据更新)

拦截 *** 作做了什么?

这里是引用

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
    // 数组对象中的每一个key设置dep,为什么在Observer里声明dep?(给每个对象加一个dep呢)
    this.dep = new Dep()
    this.vmCount = 0
    //设置__ob__属性,引用当前Observer实例
    def(value, '__ob__', this)
    //如果是数据就替换数组对象的原型
    if (Array.isArray(value) ) { 
      if (hasProto) {
        // 覆盖原型的方法
        // 把覆盖过得arrayMethods直接替换掉。这个数组以后就会通知了
        // 覆盖完7个数组方法之后,会覆盖到数组实例上
        protoAugment(value, arrayMethods)
      } else {
        copyAugment(value, arrayMethods, arrayKeys)
      }
      // 如果数组里面元素是对象还需要进行响应式处理,数组本身需要处理,数组里含有对象也需要进行处理
      this.observeArray(value)
    } else {
      //对象的话直接处理
      this.walk(value)
    }
  }
    
export function defineReactive ( 
 //dep和key一一对应
  const dep = new Dep()
  //属性拦截核心代码,只要是对象类型,均会返回childob  (这里指val)
  let childOb = !shallow && observe(val)
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
      //获取key对应的值
      const value = getter ? getter.call(obj) : val
      //如果存在依赖
      if (Dep.target) {
        //收集依赖
        dep.depend()
        if (childOb) {
          //如果存子ob,子ob也收集依赖
          childOb.dep.depend()
          if (Array.isArray(value)) {
            dependArray(value)
          }
        }
      }
      return value
    },
    set: function reactiveSetter (newVal) {
      const value = getter ? getter.call(obj) : val
      if (newVal === value || (newVal !== newVal && value !== value)) {
        return
      }
      if (process.env.NODE_ENV !== 'production' && customSetter) {
        customSetter()
      }
      if (getter && !setter) return
      if (setter) {
        setter.call(obj, newVal)
      } else {
        val = newVal
      }
      //如果新值是对象,也要做响应式
      childOb = !shallow && observe(newVal)
      //通知更新,会调用watcher.js方法进行更新
      dep.notify()
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1295845.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存