vue 数据更新驱动试图

2020-04-22  本文已影响0人  晗笑书生

官方原理图

image.png

参考如下所示:


IMG_0447 2.PNG

调试分析

image.png

数据改变 驱动试图改变的调用栈如右图所示

changeMsg this.msg === '111'的变化 触发了proxySetter(val) 代理到了this._data.msg = '111' 触发了reactiveSetter -触发setter的dep.notify 派发更新 触发了queueWatch ->nextTick -> flushCallbacks flushSchedulerQueue 触发了watcher.run 触发了渲染watcher的get求值 this.getter.call 就是 渲染watcher的 getter updateComponent 当成getter传入到渲染watcher中去的

// vm._render() 返回对应的VNode  经过patch patchNode diff 等 patch就是把vnode 映射成 dom  通过insert 插入到父节点中去
 updateComponent = function () {
      vm._update(vm._render(), hydrating);
    };
// 2次代理 代理到vm上去的
function proxy (target, sourceKey, key) {
  sharedPropertyDefinition.get = function proxyGetter () {
    return this[sourceKey][key]
  };
  sharedPropertyDefinition.set = function proxySetter (val) {
    this[sourceKey][key] = val;
  };
  Object.defineProperty(target, key, sharedPropertyDefinition);
}
Watcher.prototype.run = function run () {
  if (this.active) {
    var value = this.get();
    if (
      value !== this.value ||
      // Deep watchers and watchers on Object/Arrays should fire even
      // when the value is the same, because the value may
      // have mutated.
      isObject(value) ||
      this.deep
    ) {
      // set new value
      var oldValue = this.value;
      this.value = value;
      if (this.user) {
        try {
          this.cb.call(this.vm, value, oldValue);
        } catch (e) {
          handleError(e, this.vm, ("callback for watcher \"" + (this.expression) + "\""));
        }
      } else {
        this.cb.call(this.vm, value, oldValue);
      }
    }
  }
};
/**
 * Evaluate the getter, and re-collect dependencies.
 */
Watcher.prototype.get = function get () {
  pushTarget(this);
  var value;
// 当前vue的实例 vueComponent this.getter new渲染Watcher的定义了 updateComponent
  var vm = this.vm;
  try {
    value = this.getter.call(vm, vm);
  } catch (e) {
    if (this.user) {
      handleError(e, vm, ("getter for watcher \"" + (this.expression) + "\""));
    } else {
      throw e
    }
  } finally {
    // "touch" every property so they are all tracked as
    // dependencies for deep watching
    if (this.deep) {
      traverse(value);
    }
    popTarget();
    this.cleanupDeps();
  }
  return value
};
image.png
// mountComponent
function mountComponent (
  vm,
  el,
  hydrating
) {
  vm.$el = el;
  if (!vm.$options.render) {
    vm.$options.render = createEmptyVNode;
}
     
  callHook(vm, 'beforeMount');

  var updateComponent;

    updateComponent = function () {
      vm._update(vm._render(), hydrating);
    };


  // we set this to vm._watcher inside the watcher's constructor
  // since the watcher's initial patch may call $forceUpdate (e.g. inside child
  // component's mounted hook), which relies on vm._watcher being already defined
  new Watcher(vm, updateComponent, noop, null, true /* isRenderWatcher */);
  hydrating = false;

  // manually mounted instance, call mounted on self
  // mounted is called for render-created child components in its inserted hook
  if (vm.$vnode == null) {
    vm._isMounted = true;
    callHook(vm, 'mounted');
  }
  return vm
}
上一篇 下一篇

猜你喜欢

热点阅读