最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue響應(yīng)式原理Observer、Dep、Watcher理解

 更新時間:2019年06月06日 08:28:00   作者:蒼耳QAQ  
這篇文章主要介紹了Vue響應(yīng)式原理-理解Observer、Dep、Watcher,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

開篇

最近在學(xué)習(xí)Vue的源碼,看了網(wǎng)上一些大神的博客,看起來感覺還是蠻吃力的。自己記錄一下學(xué)習(xí)的理解,希望能夠達到簡單易懂,不看源碼也能理解的效果😆

Object.defineProperty

相信很多同學(xué)或多或少都了解Vue的響應(yīng)式原理是通過Object.defineProperty實現(xiàn)的。被Object.defineProperty綁定過的對象,會變成「響應(yīng)式」化。也就是改變這個對象的時候會觸發(fā)get和set事件。進而觸發(fā)一些視圖更新。舉個栗子🌰

function defineReactive (obj, key, val) {
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: () => {
      console.log('我被讀了,我要不要做點什么好?');
      return val;
    },
    set: newVal => {
      if (val === newVal) {
        return;
      }
      val = newVal;
      console.log("數(shù)據(jù)被改變了,我要把新的值渲染到頁面上去!");
    }
  })
}

let data = {
  text: 'hello world',
};

// 對data上的text屬性進行綁定
defineReactive(data, 'text', data.text);

console.log(data.text); // 控制臺輸出 <我被讀了,我要不要做點什么好?>
data.text = 'hello Vue'; // 控制臺輸出 <hello Vue && 數(shù)據(jù)被改變了,我要把新的值渲染到頁面上去!>

Observer 「響應(yīng)式」

Vue中用Observer類來管理上述響應(yīng)式化Object.defineProperty的過程。我們可以用如下代碼來描述,將this.data也就是我們在Vue代碼中定義的data屬性全部進行「響應(yīng)式」綁定。

class Observer {
  constructor() {
    // 響應(yīng)式綁定數(shù)據(jù)通過方法
   observe(this.data);
  }
}

export function observe (data) {
  const keys = Object.keys(data);
  for (let i = 0; i < keys.length; i++) {
    // 將data中我們定義的每個屬性進行響應(yīng)式綁定
    defineReactive(obj, keys[i]);
  }
}

Dep 「依賴管理」

什么是依賴?

相信沒有看過源碼或者剛接觸Dep這個詞的同學(xué)都會比較懵。那Dep究竟是用來做什么的呢? 我們通過defineReactive方法將data中的數(shù)據(jù)進行響應(yīng)式后,雖然可以監(jiān)聽到數(shù)據(jù)的變化了,那我們怎么處理通知視圖就更新呢?

Dep就是幫我們收集【究竟要通知到哪里的】。比如下面的代碼案例,我們發(fā)現(xiàn),雖然data中有text和message屬性,但是只有message被渲染到頁面上,至于text無論怎么變化都影響不到視圖的展示,因此我們僅僅對message進行收集即可,可以避免一些無用的工作。

那這個時候message的Dep就收集到了一個依賴,這個依賴就是用來管理data中message變化的。

<div>
  <p>{{message}}</p>
</div>
data: {
  text: 'hello world',
  message: 'hello vue',
}

當(dāng)使用watch屬性時,也就是開發(fā)者自定義的監(jiān)聽某個data中屬性的變化。比如監(jiān)聽message的變化,message變化時我們就要通知到watch這個鉤子,讓它去執(zhí)行回調(diào)函數(shù)。

這個時候message的Dep就收集到了兩個依賴,第二個依賴就是用來管理watch中message變化的。

watch: {
  message: function (val, oldVal) {
    console.log('new: %s, old: %s', val, oldVal)
  },
}    

當(dāng)開發(fā)者自定義computed計算屬性時,如下messageT屬性,是依賴message的變化的。因此message變化時我們也要通知到computed,讓它去執(zhí)行回調(diào)函數(shù)。 這個時候message的Dep就收集到了三個依賴,這個依賴就是用來管理computed中message變化的。

computed: {
  messageT() {
    return this.message + '!';
  }
}

圖示如下:一個屬性可能有多個依賴,每個響應(yīng)式數(shù)據(jù)都有一個Dep來管理它的依賴。

如何收集依賴

我們?nèi)绾沃纃ata中的某個屬性被使用了,答案就是Object.defineProperty,因為讀取某個屬性就會觸發(fā)get方法??梢詫⒋a進行如下改造:

function defineReactive (obj, key, val) {
  let Dep; // 依賴

  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: () => {
      console.log('我被讀了,我要不要做點什么好?');
      // 被讀取了,將這個依賴收集起來
      Dep.depend(); // 本次新增
      return val;
    },
    set: newVal => {
      if (val === newVal) {
        return;
      }
      val = newVal;
      // 被改變了,通知依賴去更新
      Dep.notify(); // 本次新增
      console.log("數(shù)據(jù)被改變了,我要把新的值渲染到頁面上去!");
    }
  })
}

什么是依賴

那所謂的依賴究竟是什么呢?上面的圖中已經(jīng)暴露了答案,就是Watcher。

Watcher 「中介」

Watcher就是類似中介的角色,比如message就有三個中介,當(dāng)message變化,就通知這三個中介,他們就去執(zhí)行各自需要做的變化。

Watcher能夠控制自己屬于哪個,是data中的屬性的還是watch,或者是computed,Watcher自己有統(tǒng)一的更新入口,只要你通知它,就會執(zhí)行對應(yīng)的更新方法。

因此我們可以推測出,Watcher必須要有的2個方法。一個就是通知變化,另一個就是被收集起來到Dep中去。

class Watcher {
  addDep() {
    // 我這個Watcher要被塞到Dep里去了~~
  },
  update() {
    // Dep通知我更新呢~~
  }, 
}

總結(jié)

回顧一下,Vue響應(yīng)式原理的核心就是Observer、Dep、Watcher。

Observer中進行響應(yīng)式的綁定,在數(shù)據(jù)被讀的時候,觸發(fā)get方法,執(zhí)行Dep來收集依賴,也就是收集Watcher。

在數(shù)據(jù)被改的時候,觸發(fā)set方法,通過對應(yīng)的所有依賴(Watcher),去執(zhí)行更新。比如watch和computed就執(zhí)行開發(fā)者自定義的回調(diào)方法。

本篇文章屬于入門篇,能夠先簡單的理解Observer、Dep、Watcher三者的作用和關(guān)系。后面會逐漸詳細和深入,循序漸進的理解和學(xué)習(xí)。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue實現(xiàn)兩個區(qū)域滾動條同步滾動

    vue實現(xiàn)兩個區(qū)域滾動條同步滾動

    這篇文章主要為大家詳細介紹了vue實現(xiàn)兩個區(qū)域滾動條同步滾動,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • 詳解Vue路由鉤子及應(yīng)用場景(小結(jié))

    詳解Vue路由鉤子及應(yīng)用場景(小結(jié))

    本篇文章主要介紹了詳解Vue路由鉤子及應(yīng)用場景(小結(jié)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • vue基于element的區(qū)間選擇組件

    vue基于element的區(qū)間選擇組件

    這篇文章主要介紹了vue基于element的區(qū)間選擇組件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • Vue+Bootstrap收藏(點贊)功能邏輯與具體實現(xiàn)

    Vue+Bootstrap收藏(點贊)功能邏輯與具體實現(xiàn)

    這篇文章主要為大家詳細介紹了Vue+Bootstrap收藏(點贊)功能邏輯與具體實現(xiàn),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • Proxy中代理數(shù)據(jù)攔截的方法詳解

    Proxy中代理數(shù)據(jù)攔截的方法詳解

    這篇文章主要為大家詳細介紹了Proxy中代理數(shù)據(jù)攔截的方法,文中的示例代碼講解詳細,對我們學(xué)習(xí)或工作具有一定的借鑒價值,需要的可以參考一下
    2022-12-12
  • vue3中require報錯require is not defined問題及解決

    vue3中require報錯require is not defined問題及解決

    這篇文章主要介紹了vue3中require報錯require is not defined問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • vue中使用jeecg進行前后端聯(lián)調(diào)方式

    vue中使用jeecg進行前后端聯(lián)調(diào)方式

    這篇文章主要介紹了vue中使用jeecg進行前后端聯(lián)調(diào)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vscode使用Eslint+Prettier格式化代碼的詳細操作

    vscode使用Eslint+Prettier格式化代碼的詳細操作

    這篇文章主要介紹了vscode使用Eslint+Prettier格式化代碼,本文通過圖文示例代碼相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • Vue關(guān)閉當(dāng)前頁面的方法

    Vue關(guān)閉當(dāng)前頁面的方法

    Vue中關(guān)閉當(dāng)前頁面的方法與原生JavaScript類似,都是通過window對象的close方法實現(xiàn),這篇文章主要介紹了Vue關(guān)閉當(dāng)前頁面的方法,需要的朋友可以參考下
    2023-09-09
  • 解決vant title-active-color與title-inactive-color不生效問題

    解決vant title-active-color與title-inactive-color不生效問題

    這篇文章主要介紹了解決vant title-active-color與title-inactive-color不生效問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11

最新評論

九寨沟县| 德安县| 习水县| 宜君县| 东兰县| 巍山| 漳平市| 永昌县| 焉耆| 上栗县| 股票| 保德县| 麻江县| 丰都县| 紫云| 施甸县| 阿拉善盟| 葫芦岛市| 盐津县| 德清县| 石泉县| 廉江市| 黎平县| 尖扎县| 浙江省| 淅川县| 霍邱县| 长寿区| 河东区| 临漳县| 黔南| 玛纳斯县| 抚州市| 呼图壁县| 比如县| 河北省| 隆子县| 惠东县| 安岳县| 黔西县| 禹城市|