阅读 261
Vue 数据响应式的理解

Vue 数据响应式的理解

什么是响应式?

就是你操作对象,对象就会给你一定的反应,这就是响应式。所以数据响应式就是你操作数据,数据就做出相应的反应。

比如:修改了vuedata 的数据,视图中的data数据就会被直接修改。

那么vue是如何实现数据响应式的呢?

实现数据响应式中的三个主要角色

图1.png

  • 紫色的ObserverDep:
    1. Observer是给对象的属性添加getetersetter,用于收集依赖和派发更新。
    2. Dep是收集当前对象的依赖关系,当对象的数据发生变化,dep.notify通知watcher改变数据
  • 蓝色的Watcher:观察者对象,实例有渲染watcher(render water), 计算属性 watcher (computed watcher),侦听器 watcher(user watcher三种

当然,文字的描述是很难理解清楚它们的关系和作用,可以看看下图。reactive可以理解为图1中的紫色部分

图2.png

可以看见,一个属性对应了一个Dep和可能多个Component(因为这个属性可能会被多个地方使用),每一个Component对应一个Watch,Dep属性的和Watch的中间者,换个专业的是说法Dep帮助我们依赖管理

大致思路:ObserverDep对传入的数据进行监听和代理,当数据发送变化时,调用dep.notify来通知Watcher,Watcher接受到通知,根据通知去改变数据,并渲染到视图中。

核心代码

/**
 * @name Vue数据双向绑定(响应式系统)的实现原理
 */

// observe方法遍历并包装对象属性
function observe(target) {
  // 若target是一个对象,则遍历它
  if (target && typeof target === "Object") {
    Object.keys(target).forEach((key) => {
      // defineReactive方法会给目标属性装上“监听器”
      defineReactive(target, key, target[key]);
    });
  }
}
// 定义defineReactive方法
function defineReactive(target, key, val) {
  const dep = new Dep();
  // 属性值也可能是object类型,这种情况下需要调用observe进行递归遍历
  observe(val);
  // 为当前属性安装监听器
  Object.defineProperty(target, key, {
    // 可枚举
    enumerable: true,
    // 不可配置
    configurable: false,
    get: function () {
      return val;
    },
    // 监听器函数
    set: function (value) {
      dep.notify();
    },
  });
}

class Dep {
  constructor() {
    this.subs = [];
  }

  addSub(sub) {
    this.subs.push(sub);
  }

  notify() {
    this.subs.forEach((sub) => {
      sub.update();
    });
  }
}

复制代码
文章分类
前端
文章标签