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

詳解VUE響應(yīng)式原理

 更新時(shí)間:2021年11月24日 14:47:05   作者:buler_sky  
這篇文章主要為大家介紹了vue組件通信的幾種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

1、響應(yīng)式原理基礎(chǔ)

響應(yīng)式基本原理是基于Object.defineProperty(obj, prop, descriptor),?descriptor里面可以定義get和set方法,可以在獲取屬性值事觸發(fā)get方法(可以收集依賴),設(shè)置屬性值時(shí)觸發(fā)set方法(更新依賴)。

擴(kuò)展:上面是vue2.0的響應(yīng)式基本原理,vue3.0的基本原理是Proxy,可以監(jiān)聽屬性的get和set方法,監(jiān)聽屬性的添加和刪除等等,比Object.defineProperty能力更強(qiáng),但是不兼容IE11。

2、核心對象:Dep與Watcher

Dep: vue在data里申明的每一個(gè)屬性都會生成一個(gè)Dep的實(shí)例對象,Dep.subs存儲著當(dāng)該屬性變化時(shí)需要去更新的Watcher;

Watcher: 有3種情況會生成Watcher的實(shí)例對象,分別為:

1.定義在computed里的計(jì)算屬性;

2.在watch里寫的監(jiān)聽函數(shù);

3.組件的渲染W(wǎng)atcher;

3、收集依賴與更新依賴

3.1 收集依賴

將Watcher的實(shí)例對象w分發(fā)到它所依賴的屬性的Dep中,過程如下:

1.將Dep.target = 當(dāng)前的Watcer 的實(shí)例對象w;

2.w執(zhí)行定義的函數(shù)(即在computed/watch寫的函數(shù));

3.執(zhí)行函數(shù)的過程如果使用data里定義的屬性,則會觸發(fā)屬性的get方法,get方法中Dep實(shí)例對象dep會將Dep.target中存儲的w放入到dep.subs數(shù)組中,完成依賴收集。

說明:Dep.target為當(dāng)前Watcer的實(shí)例對象

3.2 更新依賴

?當(dāng)修改我們申明的某個(gè)屬性時(shí),會觸發(fā)屬性的set方法,set方法會將dep.subs數(shù)組中收集的Watcher實(shí)例對象進(jìn)行更新,即觸發(fā)我們定義在computed和watch里面的函數(shù)。

4、源碼調(diào)試

4.1 測試的頁面代碼

<template>
  <div>
    <div>a:<input v-model="a" /></div>
    <div>c:{{ c }}</div>
    <div>b:<input v-model="b" /></div>
  </div>
</template>
<script>
export default {
  data: () => {
    return {
      a: '',
      b: ''
    }
  },
  computed: {
    c() {
      return 'source from ' + this.a;
    }
  },
  watch: {
    b() {
      console.log('b changed');
    }
  }
};
</script>

上面的代碼vue初始化后會生成如下幾個(gè)對象:

1、對象說明

屬性a和b對應(yīng)的Dep實(shí)例對象(收集a、b改變需要更新的Watcher):depAdepB;

頁面渲染函數(shù)生成對應(yīng)的Watcher實(shí)例對象updateWatcher;

computed屬性c生成對應(yīng)的Watcher實(shí)例對象:watcherC;

watch監(jiān)聽屬性b生成對應(yīng)的Watcher實(shí)例對象:watcherB;

2、Dep與Watcher的關(guān)系

a、b變化頁面需要重新渲染,所以updateWatcher存在于depAdepBsubs中;

計(jì)算屬性c依賴屬性a的變化更更新,所以watcherC存在于depA的subs中;

b的變化會觸發(fā)定義watch 里b的監(jiān)聽函數(shù),所以watcherB存在于depB的subs中;

3、最終的關(guān)系結(jié)果

最終屬性a收集的依賴 depA.subs = [?updateWatcher,? watcherC];

最終屬性b收集的依賴 depB.subs = [?updateWatcher,? watcherB];

4.2? 源碼調(diào)試

找到源碼文件:node_modules\vue\dist\vue.runtime.esm.js;

主要涉及如下幾個(gè)函數(shù):

1、收集依賴的入口函數(shù):initState(頁面初始化時(shí)執(zhí)行);

初始化順序是先data-->computed-->watch:原因是computed依賴data, watch依賴data和watch,被依賴的需要先初始化。

2、初始化computed和watch時(shí),生成Watcher實(shí)例化對象

先執(zhí)行Watcher.get函數(shù),將Dep.target = 當(dāng)前Watcher實(shí)例化對象

觸發(fā)收集依賴

執(zhí)行計(jì)算屬性里面的函數(shù),如果訪問到data中的某個(gè)屬性時(shí),會觸發(fā)data屬性的get方法,觸發(fā)依賴收集:

當(dāng)修改這個(gè)屬性時(shí)會觸發(fā)set方法,會觸發(fā)更新dep.subs里面watcher對象

最終觸發(fā)Watcher的更新函數(shù),將待更新的watcher放入隊(duì)列中:

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

最新評論

合水县| 桑植县| 内乡县| 龙门县| 祥云县| 城固县| 绿春县| 洛扎县| 宜宾市| 即墨市| 三明市| 象山县| 玉龙| 永城市| 鄂尔多斯市| 信阳市| 固阳县| 昂仁县| 赣榆县| 陇川县| 灌南县| 襄樊市| 凤翔县| 晋州市| 陆川县| 工布江达县| 德州市| 株洲县| 改则县| 忻城县| 阿坝| 吴旗县| 甘肃省| 祥云县| 察雅县| 黔江区| 长葛市| 上饶市| 蒙山县| 上思县| 溧阳市|