欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue之Watcher源碼解析(1)

 更新時間:2017年07月19日 11:47:37   作者:  
這篇文章主要為大家詳細介紹了Vue源碼之Watcher的基礎知識,具有一定的參考價值,感興趣的小伙伴們可以參考一下

上一節(jié)最后再次調用了mount函數,我發(fā)現竟然跳到了7000多行的那個函數,之前我還說因為聲明早了被覆蓋,看來我錯了!

就是這個函數:

// Line-7531
  Vue$3.prototype.$mount = function(el, hydrating) {
    el = el && inBrowser ? query(el) : undefined;
    return mountComponent(this, el, hydrating)
  };

第一步query就不用看了,el此時是一個DOM節(jié)點,所以直接返回,然后調用了mountComponent函數。

// Line-2375
  function mountComponent(vm, el, hydrating) {
    vm.$el = el;
    /* 檢測vm.$options.render */

    // 調用鉤子函數
    callHook(vm, 'beforeMount');

    var updateComponent;
    /* istanbul ignore if */
    if ("development" !== 'production' && config.performance && mark) {
      /* 標記vue-perf */
    } else {
      updateComponent = function() {
        vm._update(vm._render(), hydrating);
      };
    }

    // 生成中間件watcher
    vm._watcher = new Watcher(vm, updateComponent, noop);
    hydrating = false;

    // 調用最后一個鉤子函數
    if (vm.$vnode == null) {
      vm._isMounted = true;
      callHook(vm, 'mounted');
    }
    return vm
  }

這個函數做了三件事,調用beforeMount鉤子函數,生成Watcher對象,接著調用mounted鉤子函數。

數據雙綁、AST對象處理完后,這里的Watcher對象負責將兩者聯系到一起,上一張網上的圖片:

可以看到,之前以前把所有的組件都過了一遍,目前就剩一個Watcher了。

構造新的Watcher對象傳了3個參數,當前vue實例、updateComponent函數、空函數。

// Line-2697
  var Watcher = function Watcher(vm, expOrFn, cb, options) {
    this.vm = vm;
    // 當前Watcher添加到vue實例上
    vm._watchers.push(this);
    // 參數配置 默認為false
    if (options) {
      this.deep = !!options.deep;
      this.user = !!options.user;
      this.lazy = !!options.lazy;
      this.sync = !!options.sync;
    } else {
      this.deep = this.user = this.lazy = this.sync = false;
    }
    this.cb = cb;
    this.id = ++uid$2;
    this.active = true;
    this.dirty = this.lazy; // for lazy watchers
    this.deps = [];
    this.newDeps = [];
    // 內容不可重復的數組對象
    this.depIds = new _Set();
    this.newDepIds = new _Set();
    // 把函數變成字符串形式`
    this.expression = expOrFn.toString();
    // parse expression for getter
    if (typeof expOrFn === 'function') {
      this.getter = expOrFn;
    } else {
      this.getter = parsePath(expOrFn);
      if (!this.getter) {
        this.getter = function() {};
        "development" !== 'production' && warn(
          "Failed watching path: \"" + expOrFn + "\" " +
          'Watcher only accepts simple dot-delimited paths. ' +
          'For full control, use a function instead.',
          vm
        );
      }
    }
    // 不是懶加載類型調用get
    this.value = this.lazy ?
      undefined :
      this.get();
  };

該構造函數添加了一堆屬性,第二個參數由于是函數,直接作為getter屬性加到watcher上,將字符串后則作為expression屬性。

最后有一個value屬性,由于lazy為false,調用原型函數gei進行賦值:

// Line-2746
  Watcher.prototype.get = function get() {
    pushTarget(this);
    var value;
    var vm = this.vm;
    if (this.user) {
      try {
        value = this.getter.call(vm, vm);
      } catch (e) {
        handleError(e, vm, ("getter for watcher \"" + (this.expression) + "\""));
      }
    } else {
      // 調用之前的updateComponent
      value = this.getter.call(vm, vm);
    }
    // "touch" every property so they are all tracked as
    // dependencies for deep watching
    if (this.deep) {
      traverse(value);
    }
    popTarget();
    this.cleanupDeps();
    return value
  };

  // Line-750
  Dep.target = null;
  var targetStack = [];

  function pushTarget(_target) {
    // 默認為null 
    if (Dep.target) {
      targetStack.push(Dep.target);
    }
    // 依賴目前標記為當前watcher
    Dep.target = _target;
  }

  function popTarget() {
    Dep.target = targetStack.pop();
  }

原型方法get中,先設置了依賴收集數組Dep的target值,user屬性暫時不清楚意思,跳到了else分支,調用了getter函數。而getter就是之前的updateComponent函數:

// Line-2422
  updateComponent = function() {
    vm._update(vm._render(), hydrating);
  };

這個函數不接受參數,所以說傳進來的兩個vm并沒有什么卵用,調用這個函數會接著調用_update函數,這個是掛載到vue原型的方法:

// Line-2422
  Vue.prototype._render = function() {
    var vm = this;
    var ref = vm.$options;
    var render = ref.render;
    var staticRenderFns = ref.staticRenderFns;
    var _parentVnode = ref._parentVnode;
    // 檢測是否已掛載
    if (vm._isMounted) {
      // clone slot nodes on re-renders
      for (var key in vm.$slots) {
        vm.$slots[key] = cloneVNodes(vm.$slots[key]);
      }
    }
    // 都沒有
    vm.$scopedSlots = (_parentVnode && _parentVnode.data.scopedSlots) || emptyObject;
    if (staticRenderFns && !vm._staticTrees) {
      vm._staticTrees = [];
    }
    vm.$vnode = _parentVnode;
    // render self
    var vnode;
    try {
      // 調用之前的render字符串函數
      vnode = render.call(vm._renderProxy, vm.$createElement);
    } catch (e) {
      /* handler error */
    }
    // return empty vnode in case the render function errored out
    if (!(vnode instanceof VNode)) {
      /* 報錯 */
      vnode = createEmptyVNode();
    }
    // set parent
    vnode.parent = _parentVnode;
    return vnode
  };

方法獲取了一些vue實例的參數,比較重點的是render函數,調用了之前字符串后的ast對象:

在這里有點不一樣的地方,接下來的跳轉有點蒙,下節(jié)再說。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 詳解vue中v-bind:style效果的自定義指令

    詳解vue中v-bind:style效果的自定義指令

    這篇文章主要介紹了vue中v-bind:style效果的自定義指令,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-01-01
  • 關于vue-cli-service:command?not?found報錯引發(fā)的實戰(zhàn)案例

    關于vue-cli-service:command?not?found報錯引發(fā)的實戰(zhàn)案例

    這篇文章主要給大家介紹了關于vue-cli-service:command?not?found報錯引發(fā)的相關資料,文中通過實例代碼將解決的過程介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2023-02-02
  • Vue之Element級聯選擇器多選傳值以及回顯方式(樹形結構)

    Vue之Element級聯選擇器多選傳值以及回顯方式(樹形結構)

    這篇文章主要介紹了Vue之Element級聯選擇器多選傳值以及回顯方式(樹形結構),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Vue結合Video.js播放m3u8視頻流的方法示例

    Vue結合Video.js播放m3u8視頻流的方法示例

    本篇文章主要介紹了Vue+Video.js播放m3u8視頻流的方法示例,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • vue鼠標懸停事件實例詳解

    vue鼠標懸停事件實例詳解

    這篇文章主要介紹了vue鼠標懸停事件,本文通過示例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2019-04-04
  • Vue中引入echarts的步驟及折線圖、柱狀圖常見配置項

    Vue中引入echarts的步驟及折線圖、柱狀圖常見配置項

    這篇文章主要介紹了Vue中引入echarts的步驟及折線圖、柱狀圖常見配置項,需要的朋友可以參考下
    2023-11-11
  • vue el-select綁定對象時,回顯內容不正確,始終是最后一項的解決

    vue el-select綁定對象時,回顯內容不正確,始終是最后一項的解決

    這篇文章主要介紹了vue el-select綁定對象時,回顯內容不正確,始終是最后一項的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • vue3中的useAttrs和props的區(qū)別解析

    vue3中的useAttrs和props的區(qū)別解析

    在vue3中,?提供了一個?useAttrs?的方法它接收到的參數一?prop中可以接收到的數據是基本一樣的如果我們想自已寫一個組件,?把?elementPlus?中的期中一個組件封裝一下,這篇文章主要介紹了vue3中的useAttrs和props的區(qū)別,需要的朋友可以參考下
    2023-09-09
  • vue-cli 2.*中導入公共less文件的方法步驟

    vue-cli 2.*中導入公共less文件的方法步驟

    這篇文章主要介紹了vue-cli 2.*中導入公共less文件的方法步驟,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • 去掉vue 中的代碼規(guī)范檢測兩種方法(Eslint驗證)

    去掉vue 中的代碼規(guī)范檢測兩種方法(Eslint驗證)

    我們在使用vue 腳手架時,為了規(guī)范團隊的代碼格式,會有一個代碼規(guī)范檢測,如果不符合規(guī)范就會報錯,有時候我們不想按照他的規(guī)范去寫。這時我們需要關閉,這里腳本之家小編給大家?guī)砹巳サ魐ue 中的代碼規(guī)范檢測兩種方法(Eslint驗證),一起看看吧
    2018-03-03

最新評論