中文字幕第五页-中文字幕第页-中文字幕韩国-中文字幕最新-国产尤物二区三区在线观看-国产尤物福利视频一区二区

怎么理解Vue3.0的響應式系統

這篇文章主要介紹“怎么理解Vue 3.0的響應式系統”,在日常操作中,相信很多人在怎么理解Vue 3.0的響應式系統問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么理解Vue 3.0的響應式系統”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

創新互聯一直秉承“誠信做人,踏實做事”的原則,不欺瞞客戶,是我們最起碼的底線! 以服務為基礎,以質量求生存,以技術求發展,成交一個客戶多一個朋友!為您提供成都網站制作、網站設計、成都網頁設計、小程序定制開發、成都網站開發、成都網站制作、成都軟件開發、成都app軟件開發是成都本地專業的網站建設和網站設計公司,等你一起來見證!

一個基本的例子

Vue 3.0 的響應式系統是獨立的模塊,可以完全脫離 Vue 而使用,所以我們在 clone 了源碼下來以后,可以直接在 packages/reactivity 模塊下調試。

  1.  在項目根目錄運行 yarn dev reactivity,然后進入 packages/reactivity 目錄找到產出的 dist/reactivity.global.js 文件。

  2.  新建一個 index.html,寫入如下代碼:   

<script src="./dist/reactivity.global.js"></script>     <script>     const { reactive, effect } = VueObserver     const origin = {       count: 0     }     const state = reactive(origin)     const fn = () => {       const count = state.count       console.log(`set count to ${count}`)     }     effect(fn)     </script>

    3.  在瀏覽器打開該文件,于控制臺執行 state.count++,便可看到輸出 set count to 1。

在上述的例子中,我們使用 reactive() 函數把 origin 對象轉化成了 Proxy 對象 state;使用 effect() 函數把 fn() 作為響應式回調。當 state.count 發生變化時,便觸發了 fn()。接下來我們將以這個例子結合上文的流程圖,來講解這套響應式系統是怎么運行的。

初始化階段

怎么理解Vue 3.0的響應式系統

在初始化階段,主要做了兩件事。

  1.  把 origin 對象轉化成響應式的 Proxy 對象 state。

  2.  把函數 fn() 作為一個響應式的 effect 函數。

首先我們來分析第一件事。

大家都知道,Vue 3.0 使用了 Proxy 來代替之前的 Object.defineProperty(),改寫了對象的 getter/setter,完成依賴收集和響應觸發。但是在這一階段中,我們暫時先不管它是如何改寫對象的 getter/setter 的,這個在后續的”依賴收集階段“會詳細說明。為了簡單起見,我們可以把這部分的內容濃縮成一個只有兩行代碼的 reactive() 函數:

export function reactive(target) {    const observed = new Proxy(target, handler)    return observed  }

完整代碼在 reactive.js。這里的 handler 就是改造 getter/setter 的關鍵,我們放到后文講解。

接下來我們分析第二件事。

當一個普通的函數 fn() 被 effect() 包裹之后,就會變成一個響應式的 effect 函數,而 fn() 也會被立即執行一次。

由于在 fn() 里面有引用到 Proxy 對象的屬性,所以這一步會觸發對象的 getter,從而啟動依賴收集。

除此之外,這個 effect 函數也會被壓入一個名為”activeReactiveEffectStack“(此處為 effectStack)的棧中,供后續依賴收集的時候使用。

來看看代碼(完成代碼請看 effect.js):

export function effect (fn) {    // 構造一個 effect    const effect = function effect(...args) {      return run(effect, fn, args)    }    // 立即執行一次    effect()    return effect  }  export function run(effect, fn, args) {    if (effectStack.indexOf(effect) === -1) {      try {        // 往池子里放入當前 effect        effectStack.push(effect)        // 立即執行一遍 fn()        // fn() 執行過程會完成依賴收集,會用到 effect        return fn(...args)      } finally {        // 完成依賴收集后從池子中扔掉這個 effect        effectStack.pop()      }    }  }

至此,初始化階段已經完成。接下來就是整個系統最關鍵的一步&mdash;&mdash;依賴收集階段。

依賴收集階段

怎么理解Vue 3.0的響應式系統

這個階段的觸發時機,就是在 effect 被立即執行,其內部的 fn() 觸發了 Proxy 對象的 getter 的時候。簡單來說,只要執行到類似 state.count 的語句,就會觸發 state 的 getter。

依賴收集階段最重要的目的,就是建立一份”依賴收集表“,也就是圖示的”targetMap"。targetMap 是一個 WeakMap,其 key 值是當前的 Proxy 對象 state代理前的對象origin,而 value 則是該對象所對應的 depsMap。

depsMap 是一個 Map,key 值為觸發 getter 時的屬性值(此處為 count),而 value 則是觸發過該屬性值所對應的各個 effect。

還是有點繞?那么我們再舉個例子。假設有個 Proxy 對象和 effect 如下:

const state = reactive({    count: 0,    age: 18  })  const effecteffect1 = effect(() => {    console.log('effect1: ' + state.count)  })  const effecteffect2 = effect(() => {    console.log('effect2: ' + state.age)  })  const effecteffect3 = effect(() => {    console.log('effect3: ' + state.count, state.age)  })

那么這里的 targetMap 應該為這個樣子:

怎么理解Vue 3.0的響應式系統

這樣,{ target -> key -> dep } 的對應關系就建立起來了,依賴收集也就完成了。代碼如下:

export function track (target, operationType, key) {    const effect = effectStack[effectStack.length - 1]    if (effect) {      let depsMap = targetMap.get(target)      if (depsMap === void 0) {        targetMap.set(target, (depsMap = new Map()))      }      let dep = depsMap.get(key)      if (dep === void 0) {        depsMap.set(key, (dep = new Set()))      }      if (!dep.has(effect)) {        dep.add(effect)      }    }  }

弄明白依賴收集表 targetMap 是非常重要的,因為這是整個響應式系統核心中的核心。

響應階段

回顧上一章節的例子,我們得到了一個 { count: 0, age: 18 } 的 Proxy,并構造了三個 effect。在控制臺上看看效果:

怎么理解Vue 3.0的響應式系統

效果符合預期,那么它是怎么實現的呢?首先來看看這個階段的原理圖:

怎么理解Vue 3.0的響應式系統

當修改對象的某個屬性值的時候,會觸發對應的 setter。

setter 里面的 trigger() 函數會從依賴收集表里找到當前屬性對應的各個 dep,然后把它們推入到 effects 和 computedEffects(計算屬性) 隊列中,最后通過 scheduleRun() 挨個執行里面的 effect。

由于已經建立了依賴收集表,所以要找到屬性所對應的 dep 也就輕而易舉了,可以看看具體的代碼實現:

export function trigger (target, operationType, key) {    // 取得對應的 depsMap    const depsMap = targetMap.get(target)    if (depsMap === void 0) {      return    }    // 取得對應的各個 dep    const effects = new Set()    if (key !== void 0) {      const dep = depsMap.get(key)      dep && dep.forEach(effect => {        effects.add(effect)      })    }    // 簡化版 scheduleRun,挨個執行 effect    effects.forEach(effect => {      effect()    })  }

這里的代碼沒有處理諸如數組的 length 被修改的一些特殊情況,感興趣的讀者可以查看 vue-next 對應的源碼,或者這篇文章,看看這些情況都是怎么處理的。

至此,響應式階段完成。

到此,關于“怎么理解Vue 3.0的響應式系統”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注創新互聯網站,小編會繼續努力為大家帶來更多實用的文章!

分享標題:怎么理解Vue3.0的響應式系統
分享鏈接:http://www.2m8n56k.cn/article12/jjdsdc.html

成都網站建設公司_創新互聯,為您提供服務器托管標簽優化網站制作自適應網站網站收錄企業網站制作

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:[email protected]。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都網站建設公司
主站蜘蛛池模板: 精品国产呦系列在线看 | 亚洲美女精品视频 | 国产香蕉久久 | 亚洲成a人片在线观看中 | 男女交性拍拍拍高清视频 | 国产精品理论片 | 真正国产乱子伦高清对白 | 亚洲欧美日韩在线观看二区 | 成人区精品一区二区毛片不卡 | 男女上下爽无遮挡午夜免费视频 | 日韩亚洲欧美一区 | 国产精品成人不卡在线观看 | 欧美激情中文字幕 | 成人免费观看永久24小时 | 国产菲菲视频在线观看 | 大焦伊人 | 久草免费在线观看 | 中文字幕一区二区三区精品 | 一区两区三不卡 | 曰本毛片va看到爽不卡 | 国产精品久久久久久久久久免费 | 久久99国产精品久久99 | 丝袜黄色片 | 国产精品久久久天天影视香蕉 | 手机在线观看a | 2022日韩理论片在线观看 | 中日韩美中文字幕 | 亚洲欧美综合国产精品一区 | 九九热视频在线免费观看 | 中文字幕一区二区三区在线观看 | aaaaaaa一级毛片 | 亚洲国语在线视频手机在线 | se94se欧美综合色 | 国产激情一级毛片久久久 | 久草一级片 | 黄网在线观看免费网站台湾swag | 日韩欧美国产精品第一页不卡 | 欧美性猛片xxxxⅹ免费 | 在线播放成人高清免费视频 | 国产精品高清在线观看地址 | 日韩免费在线视频 |