Vue响应式原理

    1、Vue内部如何监听message数据改变?  Object.defineProperty
Object.defineProperty(obj, prop, descriptor)
obj:需要定义属性的对象
prop:要定义或修改的属性的名称或Symbol
descriptor:要定义或修改的属性描述符
    2、数据改变,Vue如何通知刷新?     发布订阅模式

 

 

 

简单的发布订阅模式梳理(即图的上半部分,下半部分编译暂时不写):

1、首先定义一个数据data对象

    const obj = {
      message: '111',
      age: 18
    }

2、使用object.defineProperty劫持数据。forEach遍历obj内的属性,通过set和get函数进行指定操作:set监听改变情况并赋新值;get拿到当前值

    Object.keys(obj).forEach(key => {
      let value = obj[key]
      //劫持
      Object.defineProperty(obj, key, {
        //设置,改变值,赋新值newValue
        set(newValue) {
          //监听某个值的改变,这里是message,当然,要是obj内还有多个数据,就遍历整个obj,对指定的key进行改变
          console.log('监听到改变  ' + key);
          value = newValue
          //解析HTMl代码获取哪些元素需要该属性,这时就来到get
          //需要用的元素会调用get,一旦set后,便通知所需要改变的元素:发布订阅模式
          dep.notify()
        },
        //获取值,拿到原Value
        get() {
          //获取改变值
          console.log('已经拿到已有值');
          return value
        }
      })
    })

  这一步即可在控制台改变数据,log打印监听到何值改变或者拿到何值

3、分别定义订阅者和发布者:

  3.1:订阅者:保存元素的名称,并使用update函数更新

    class Watcher {
      constructor(name) {
        //保存某个元素
        this.name = name
      }

      update() {
        console.log(this.name + '元素发生update');
      }
    }

  3.2:发布者:首先构造函数将所要监听的订阅者放置一个数组内(即元素,这里要注意,每一个元素每一个属性都对应一个dep,这样才能针对不同的元素,不同的属性发布不同的内容),然后执行notify通知函数(其实就是forEach遍历数组内的watcher,执行内部的update函数

    //发布:一个属性对应一个Dep,message一个,age一个,这样才能针对不同的对象,不同的属性进行分别通知或者说发布
    class Dependence {
      constructor() {
        //记录那些元素需要订阅数据
        this.subscribes = []
      }
      addSub(watcher) {
        this.subscribes.push(watcher)
      }
      notify() {
        console.log('发布')
        this.subscribes.forEach(item => {
          item.update()
        })
      }
    }

4、执行过程:new一个dep监听数据改变,在new多个需要监听的watcher,将watcher推入dep中准备发布

    const dep = new Dependence()
    //某个元素已经被创建保存,element1
    const watch1 = new Watcher('el1')
    //元素加入到dep内记录监听
    dep.addSub(watch1)

 

执行结果:

 

 

 

其他的就是下半部分的compile,上述为手动push

 

 

 

 

 

posted @ 2021-11-09 22:07  Jacky02  阅读(42)  评论(0)    收藏  举报