Vue响应式原理

一、简介

Vue 最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。这使得状态管理非常简单直接,不过理解其工作原理同样重要,这样你可以避开一些常见的问题。在这个章节,我们将研究一下 Vue 响应式系统的底层的细节。

Vue的数据双向绑定,响应式原理,其实就是通过Object.defineProperty()结合发布者订阅者模式来实现的。

Vue响应式原理_第1张图片

const obj = {
  message:'hhhh',
  name: 'why',
}

Object.keys(obj).forEach(key => {
  let value = obj[key];

  Object.defineProperty(obj, key, {
    set(newValue){
      console.log('监听' + key + '改变 ')
      value = newValue;
    },
    get(){
      console.log('获取' + key + '对应的值')
      return value
    }
  })
})

在这里插入图片描述
在这里插入图片描述

Object.defineProperty()监听对象属性的改变
发布者订阅者模式通知需要改变的地方

Vue 的响应式原理是核心是通过 ES5 的保护对象的 Object.defindeProperty 中的访问器属性中的 get 和 set 方法,data 中声明的属性都被添加了访问器属性,当读取 data 中的数据时自动调用 get 方法,当修改 data 中的数据时,自动调用 set 方法,检测到数据的变化,会通知观察者 Wacher,观察者 Wacher自动触发重新render 当前组件(子组件不会重新渲染),生成新的虚拟 DOM 树,Vue 框架会遍历并对比新虚拟 DOM 树和旧虚拟 DOM 树中每个节点的差别,并记录下来,最后,加载操作,将所有记录的不同点,局部修改到真实 DOM 树上。

Vue响应式原理_第2张图片

//发布者
class Dep {
    constructor () {
        /* 用来存放Watcher对象的数组 */
        this.subs = [];
    }
    /* 在subs中添加一个Watcher对象 */
    addSub (sub) {
        this.subs.push(sub);
    }
    /* 通知所有Watcher对象更新视图 */
    notify () {
        this.subs.forEach((sub) => {
            sub.update();
        })
    }
}

//订阅者
class Watcher {
  constructor(name) {
  	this.name = name
  }
  update() {
    // 获得新值
   console.log(this.name + '发生update');
  }
}

const dep = new Dep();

const w1 = new Watcher('张三');
dep.addSub(w1)

const w2 = new Watcher('李四);
dep.addSub(w2)

const w3 = new Watcher('王五');
dep.addSub(w3)

dep.notify()

在这里插入图片描述
Vue响应式原理_第3张图片

在 Observer阶段,会为每个 key 都创建一个 dep 实例。并且,如果该 key 被某个 watcher 实例 get, 把该 watcher 实例加入 dep 实例的队列里。如果该 key 被 set, 则通知该 key 对应的 dep 实例, 然后 dep 实例会将依次通知队列里的 watcher 实例, 让它们去执行自身的回调方法

dep 实例是收集该 key 所有 watcher 实例的地方.

watcher 实例用来监听某个 key ,如果该 key 产生变化,便会执行 watcher 实例自身的回调

Vue响应式原理_第4张图片

你可能感兴趣的:(Vue)