美文网首页
vue 响应式对象原理源码分析

vue 响应式对象原理源码分析

作者: Wendy81 | 来源:发表于2020-11-11 16:31 被阅读0次

响应式对象原理
这节我们知道对象响应式原理的实现,在此基础上分析vue的响应式

image.png

一、初始化实例_init函数

 Vue.prototype._init = function (options) {
  ......
    initInjections(vm); // resolve injections before data/props
  ......
  };

二、查看initInjections函数

function initInjections (vm) {
  var result = resolveInject(vm.$options.inject, vm);
  if (result) {
    ......
    Object.keys(result).forEach(function (key) {
      /* istanbul ignore else */
      if (process.env.NODE_ENV !== 'production') {
        defineReactive$$1(vm, key, result[key], function () {
         ......
      } else {
       ......
      }
    });
    ......
  }
}

三、接着查看defineReactive$$1函数

function defineReactive$$1 (
  obj,
  key,
  val,
  customSetter,
  shallow
) {
  var dep = new Dep();
  ......
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
      ......
      if (Dep.target) {
        dep.depend();
        ......
      }
      return value
    },
    set: function reactiveSetter (newVal) {
      ......
      if (setter) {
        setter.call(obj, newVal);
      } else {
        val = newVal;
      }
      ......
      dep.notify();
    }
  });
}

实现的原理实际上也就是把要响应数据用Object.defineProperty改成getter/setter存储器属性:

1.get()函数中调用 dep.depend(),实现this.subs.push(target)
2.set()函数中调用dep.notify();运行this.subs数据中的所有函数,实现存储最新数据的操作

更详细的可以查看 class Dep相关定义

var Dep = function Dep () {
  this.id = uid++;
  this.subs = [];
};

Dep.prototype.depend = function depend () {
  if (Dep.target) {
    Dep.target.addDep(this);
  }
};

Dep.prototype.notify = function notify () {
  // stabilize the subscriber list first
  var subs = this.subs.slice();
  if (process.env.NODE_ENV !== 'production' && !config.async) {
    // subs aren't sorted in scheduler if not running async
    // we need to sort them now to make sure they fire in correct
    // order
    subs.sort(function (a, b) { return a.id - b.id; });
  }
  for (var i = 0, l = subs.length; i < l; i++) {
    subs[i].update();
  }
};

注意:Dep.target就是watcher实例,即是一个对象

?同一时间只有一个watcher可以被push进targetStack

Dep.target = null;
var targetStack = [];

function pushTarget (target) {
  targetStack.push(target);
  Dep.target = target;
}

function popTarget () {
  targetStack.pop();
  Dep.target = targetStack[targetStack.length - 1];
}

相关文章

网友评论

      本文标题:vue 响应式对象原理源码分析

      本文链接:https://www.haomeiwen.com/subject/pueebktx.html