精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

圖解 Vue 異步更新原理

開發 前端
本文主要分析 Vue 從 Data 更新,到通知 Watcher 異步更新視圖的流程,也就是下圖中的橙色部分。

[[340964]]

本文轉載自微信公眾號「 前端日志」,作者 前端日志。轉載本文請聯系 前端日志公眾號。

 本文主要分析 Vue 從 Data 更新,到通知 Watcher 異步更新視圖的流程,也就是下圖中的橙色部分。

 

我們先來回顧一下圖中的幾個對象:

  • Data 對象:Vue 中的 data 方法中返回的對象。
  • Dep 對象:每一個 Data 屬性都會創建一個 Dep,用來搜集所有使用到這個 Data 的 Watcher 對象。
  • Watcher 對象:主要用于渲染 DOM。

接下來,我們就開始分析這個流程。

Vue 異步更新 DOM 原理

很多同學都知道,Vue 中的數據更新是異步的,意味著我們在修改完 Data 之后,并不能立刻獲取修改后的 DOM 元素。

例如:

  1. <template> 
  2.   <div> 
  3.     <span id="text">{{ message }}</span> 
  4.     <button @click="changeData"
  5.       changeData 
  6.     </button> 
  7.   </div> 
  8. </template> 
  9.  
  10. <script> 
  11. export default { 
  12.   data() { 
  13.     return { 
  14.       message: "hello"
  15.     }; 
  16.   }, 
  17.   methods: { 
  18.     changeData() { 
  19.       this.message = "hello world"
  20.       const textContent = document.getElementById("text").textContent; 
  21.       // 直接獲取,不是最新的 
  22.       console.log(textContent === "hello world"); // false 
  23.             // $nextTick 回調中,是最新的 
  24.       this.$nextTick(() => { 
  25.         const textContent = document.getElementById("text").textContent; 
  26.         console.warn(textContent === "hello world"); // true 
  27.       }); 
  28.     }, 
  29.   }, 
  30. }; 
  31. </script> 

 

什么時候我們才能獲取到真正的 DOM 元素?

答:在 Vue 的 nextTick 回調中。

這一點在 Vue 官網有詳細的介紹,但你是否有想過,為什么 Vue 需要通過 nextTick 方法才能獲取最新的 DOM?

帶著這個疑問,我們直接看一下源碼。

  1. // 當一個 Data 更新時,會依次執行以下代碼 
  2. // 1. 觸發 Data.set 
  3. // 2. 調用 dep.notify 
  4. // 3. Dep 會遍歷所有相關的 Watcher 執行 update 方法 
  5. class Watcher { 
  6.   // 4. 執行更新操作 
  7.   update() { 
  8.     queueWatcher(this); 
  9.   } 
  10.  
  11. const queue = []; 
  12.  
  13. function queueWatcher(watcher: Watcher) { 
  14.   // 5. 將當前 Watcher 添加到異步隊列 
  15.   queue.push(watcher); 
  16.   // 6. 執行異步隊列,并傳入回調 
  17.   nextTick(flushSchedulerQueue); 
  18.  
  19. // 更新視圖的具體方法 
  20. function flushSchedulerQueue() { 
  21.   let watcher, id; 
  22.   // 排序,先渲染父節點,再渲染子節點 
  23.   // 這樣可以避免不必要的子節點渲染,如:父節點中 v-if 為 false 的子節點,就不用渲染了 
  24.   queue.sort((a, b) => a.id - b.id); 
  25.   // 遍歷所有 Watcher 進行批量更新。 
  26.   for (index = 0; index < queue.length; index++) { 
  27.     watcher = queue[index]; 
  28.     // 更新 DOM 
  29.     watcher.run(); 
  30.   } 

根據上面的代碼,我們可以得出這樣一個流程圖:

 

圖中可以看到,Vue 在調用 Watcher 更新視圖時,并不會直接進行更新,而是把需要更新的 Watcher 加入到 Queue 隊列里,然后把具體的更新方法 flushSchedulerQueue 傳給 nextTick 進行調用。

接下來,我們分析一下 nextTick。

  1. const callbacks = []; 
  2. let timerFunc; 
  3.  
  4. function nextTick(cb?: Function, ctx?: Object) { 
  5.   let _resolve; 
  6.   // 1.將傳入的 flushSchedulerQueue 方法添加到回調數組 
  7.   callbacks.push(() => { 
  8.     cb.call(ctx); 
  9.   }); 
  10.   // 2.執行異步任務 
  11.   // 此方法會根據瀏覽器兼容性,選用不同的異步策略 
  12.   timerFunc(); 

可以看到,nextTick 函數非常簡單,它只是將傳入的 flushSchedulerQueue 添加到 callbacks 數組中,然后執行了 timerFunc 方法。

接下來,我們分析一下 timerFunc 方法。

  1. let timerFunc; 
  2. // 判斷是否兼容 Promise 
  3. if (typeof Promise !== "undefined") { 
  4.   timerFunc = () => { 
  5.     Promise.resolve().then(flushCallbacks); 
  6.   }; 
  7.   // 判斷是否兼容 MutationObserver 
  8.   // https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver 
  9. else if (typeof MutationObserver !== "undefined") { 
  10.   let counter = 1; 
  11.   const observer = new MutationObserver(flushCallbacks); 
  12.   const textNode = document.createTextNode(String(counter)); 
  13.   observer.observe(textNode, { 
  14.     characterData: true
  15.   }); 
  16.   timerFunc = () => { 
  17.     counter = (counter + 1) % 2; 
  18.     textNode.data = String(counter); 
  19.   }; 
  20.   // 判斷是否兼容 setImmediate 
  21.   // 該方法存在一些 IE 瀏覽器中 
  22. else if (typeof setImmediate !== "undefined") { 
  23.   // 這是一個宏任務,但相比 setTimeout 要更好 
  24.   timerFunc = () => { 
  25.     setImmediate(flushCallbacks); 
  26.   }; 
  27. else { 
  28.   // 如果以上方法都不知道,使用 setTimeout 0 
  29.   timerFunc = () => { 
  30.     setTimeout(flushCallbacks, 0); 
  31.   }; 
  32.  
  33. // 異步執行完后,執行所有的回調方法,也就是執行 flushSchedulerQueue 
  34. function flushCallbacks() { 
  35.   for (let i = 0; i < copies.length; i++) { 
  36.     callbacks[i](); 
  37.   } 

可以看到,timerFunc 是根據瀏覽器兼容性創建的一個異步方法,它執行完成之后,會調用 flushSchedulerQueue 方法進行具體的 DOM 更新。

分析到這里,我們就可以得到一張整體的流程圖了。

 

接下來,我們來完善一些判斷邏輯。

  • 判斷 has 標識,避免在一個 Queue 中添加相同的 Watcher。
  • 判斷 waiting 標識,讓所有的 Watcher 都在一個 tick 內進行更新。
  • 判斷 flushing 標識,處理 Watcher 渲染時,可能產生的新 Watcher。

如:觸發了 v-if 的條件,新增的 Watcher 渲染。

結合以上判斷,最終的流程圖如下:

 

最后,我們分析一下,為什么 this.$nextTick 能夠獲取更新后的 DOM?

  1. // 我們使用 this.$nextTick 其實就是調用 nextTick 方法 
  2. Vue.prototype.$nextTick = function (fn: Function) { 
  3.   return nextTick(fn, this); 
  4. }; 

可以看到,調用 this.$nextTick 其實就是調用了圖中的 nextTick 方法,在異步隊列中執行回調函數。根據先來后到原則,修改 Data 觸發的更新異步隊列會先得到執行,執行完成后就生成了新的 DOM ,接下來執行 this.$nextTick 的回調函數時,能獲取到更新后的 DOM 元素了。

由于 nextTick 只是單純通過 Promise 、SetTimeout 等方法模擬的異步任務,所以也可以手動執行一個異步任務,來實現和 this.$nextTick 相同的效果。

  1. this.message = "hello world"
  2. // 手動執行一個異步任務,也能獲取最新的 DOM 
  3. Promise.resolve().then(() => { 
  4.   const textContent = document.getElementById("text").textContent; 
  5.   console.log(textContent === "hello world"); // true 
  6. }); 
  7. setTimeout(() => { 
  8.   const textContent = document.getElementById("text").textContent; 
  9.   console.log(textContent === "hello world"); // true 
  10. }); 

思考與總結

本文從源碼的角度,介紹了 Vue 異步更新的原理,來簡單回顧一下吧。

修改 Vue 中的 Data 時,就會觸發所有和這個 Data 相關的 Watcher 進行更新。

首先,會將所有的 Watcher 加入隊列 Queue。

然后,調用 nextTick 方法,執行異步任務。

在異步任務的回調中,對 Queue 中的 Watcher 進行排序,然后執行對應的 DOM 更新。

責任編輯:武曉燕 來源: 前端日志
相關推薦

2020-09-21 14:35:20

VuenextTick前端

2025-09-19 10:00:28

2021-02-05 15:01:41

GitLinux命令

2021-06-09 10:29:23

Kafka架構組件

2021-04-09 08:54:14

Kafka源碼架構開發技術

2021-12-07 07:32:09

kafka架構原理

2021-08-02 07:57:03

注冊Nacos源碼

2024-10-30 10:06:51

2022-11-08 00:00:00

監控系統Prometheus

2024-03-08 10:38:07

Vue響應式數據

2020-11-30 07:54:46

ElasticSear開源分布式

2017-12-26 17:42:12

前端WebGLThree.js

2020-12-09 10:29:53

SSH加密數據安全

2010-02-04 10:17:38

Android應用程序

2023-09-19 08:12:18

2023-01-04 13:43:24

讀寫鎖AQS共享模式

2020-09-14 08:56:30

Vue模板

2021-05-19 09:29:52

VueAxios異步請求

2021-09-29 11:33:19

異步組件Vue 3

2022-08-30 09:01:11

瀏覽器渲染前端
點贊
收藏

51CTO技術棧公眾號

欧美一级在线亚洲天堂| 91精品麻豆日日躁夜夜躁| 成人免费在线一区二区三区| 欧美成人精品欧美一| 九九99久久精品在免费线bt| 夜夜精品视频一区二区| 91视频免费网站| 久久久久成人网站| 丝袜美腿一区二区三区动态图| 色综合一个色综合| 亚洲精品一区国产精品| 国产三级小视频| 在线午夜精品| 中文字幕在线观看日韩| 欧洲成人午夜精品无码区久久| 成人黄色动漫| 国产精品丝袜一区| 亚洲一区制服诱惑| 精品成人av一区二区在线播放| 国产一区二区欧美| 日韩欧美一级精品久久| 女人喷潮完整视频| 视频一区二区三区不卡| 国产不卡视频在线播放| 国产成人精品av| 三级黄色在线观看| 女人抽搐喷水高潮国产精品| 欧美日韩在线不卡| 精品久久久久久无码中文野结衣| 视频福利在线| 国产一区二区美女| 欧美专区中文字幕| 久草免费新视频| 日韩欧美一区免费| 亚洲美女视频网| 最好看的中文字幕| 狠狠久久综合| 亚洲成人一区二区| 一区二区三区日韩视频| 五月天婷婷社区| 国产高清一区日本| 国产精品一区二区三| 国产福利拍拍拍| 久久精品国内一区二区三区水蜜桃| 亚洲欧美日韩中文在线制服| 免费看黄色aaaaaa 片| 1204国产成人精品视频| 91精品国产综合久久久蜜臀图片| 国产精品人人爽人人爽| 亚洲第一二三四区| 色成年激情久久综合| 情侣黄网站免费看| 性欧美1819sex性高清| 日本精品一区二区三区四区的功能| 老子影院午夜伦不卡大全| 青春草视频在线观看| 亚洲精品免费在线观看| 在线观看18视频网站| 二区三区在线观看| 亚洲另类春色国产| 国产xxxx振车| 九色porny自拍视频在线观看| 亚洲国产裸拍裸体视频在线观看乱了| 成年丰满熟妇午夜免费视频 | 中文字幕日韩精品在线观看| 一区二区三区伦理片| 欧美一区二区三| 色悠悠久久久久| 东方av正在进入| 国产精品扒开腿做爽爽爽软件| 欧美日韩国产成人高清视频| 日本系列第一页| 性感少妇一区| 国产一区二区在线免费视频| 99久久精品日本一区二区免费| 国产69精品久久777的优势| 成人免费视频视频在| 日韩精品视频在线观看一区二区三区| 久久久久高清精品| 正在播放一区二区三区| 在线网址91| 欧美午夜精品久久久久久浪潮| 99免费视频观看| av成人在线网站| 亚洲第一区在线| 黄色片在线观看免费| 欧美aa国产视频| 欧美亚洲激情在线| 91九色蝌蚪91por成人| 高潮精品一区videoshd| 日韩免费一区二区三区| a毛片在线看免费观看| 天天综合天天综合色| 性猛交ⅹ×××乱大交| 亚洲免费一区三区| 在线视频免费一区二区| 久草视频免费在线| 日韩电影在线看| 国产精品免费看一区二区三区| 国产三级视频在线播放线观看| 一区二区三区 在线观看视频| 日韩欧美精品在线观看视频| 国产乱码精品一区二区三区亚洲人 | 国产99久久| 欧美日本高清视频| 国产精品成人无码| 99久久99久久综合| 午夜啪啪福利视频| 日本韩国欧美| 亚洲电影免费观看| 午夜激情福利网| 另类av一区二区| 国产日本一区二区三区| 麻豆视频在线观看免费网站| 色94色欧美sute亚洲线路一ni| 野花视频免费在线观看| 99精品全国免费观看视频软件| 91爱视频在线| 涩涩视频免费看| 一区二区三区精品在线观看| 九九九九九国产| 国产区精品区| 欧美中文在线视频| 四虎免费在线观看| 一区二区三区日韩欧美| 最新天堂在线视频| av在线不卡顿| 国产成人综合亚洲| 青青视频在线观| 香蕉影视欧美成人| 91传媒理伦片在线观看| 欧美日本一区| 91超碰rencao97精品| 国产在线看片| 欧美久久一二三四区| 免费看的黄色网| 日韩精品午夜视频| 任我爽在线视频精品一| 悠悠资源网亚洲青| 亚洲国产精品美女| 国产在线视频第一页| 国产一区二区精品久久99| 宅男在线精品国产免费观看| 欧洲美女精品免费观看视频| 中文字幕少妇一区二区三区| 午夜视频网站在线观看| 欧美国产禁国产网站cc| 国产成人黄色网址| 奇米影视亚洲| 国产在线日韩在线| 欧美猛烈性xbxbxbxb| 欧美日韩免费视频| 欧美性生交大片| 极品尤物av久久免费看| 公共露出暴露狂另类av| 精品中文字幕一区二区三区| 欧美激情视频给我| 蜜臀久久精品久久久久| 欧美日韩免费在线| brazzers精品成人一区| 青青草精品视频| 天天干天天色天天爽| 日本一区精品视频| 久久久久国产精品一区| 天堂av网在线| 欧美亚洲丝袜传媒另类| 亚洲一区电影在线观看| 国产在线乱码一区二区三区| 国产91精品入口| 国产午夜精品久久久久久免费视 | 欧美日韩国产欧美日美国产精品| 亚洲激情图片网| 狠狠色丁香婷婷综合久久片| 国产精品一二三在线观看| 99国产精品免费网站| 欧美一级黑人aaaaaaa做受| 国产一级免费在线观看| 91精品免费在线| 国产无码精品在线播放| 国产亚洲欧美一级| 九九九九九九九九| 在线国产精品一区| 欧美一卡2卡3卡4卡无卡免费观看水多多 | 欧美日韩激情在线一区二区三区| 国产区精品视频| 丰满的护士2在线观看高清| 亚洲免费电影在线观看| 夜夜躁很很躁日日躁麻豆| 亚洲一区二区三区美女| 亚洲国产天堂av| 国产高清不卡一区| 日本中文字幕片| 68国产成人综合久久精品| 国产欧美一区二区视频| 日韩漫画puputoon| 欧美肥老妇视频| 国产精品一二三区视频| 欧美一区二区三区系列电影| 国产一级片毛片| 亚洲人123区| 亚洲精品国产91| 成人一区二区在线观看| 日本免费色视频| 米奇777在线欧美播放| 丰满女人性猛交| 免费视频亚洲| 国产女人水真多18毛片18精品| 成人免费毛片嘿嘿连载视频…| 欧美激情精品久久久久久大尺度| 成人精品一区二区三区校园激情| 精品日产卡一卡二卡麻豆| 最新中文字幕第一页| 精品毛片三在线观看| 中文字幕在线有码| 国产片一区二区三区| 手机免费看av片| 国产精品正在播放| 美女网站视频黄色| 久久久久免费| 国产日韩av网站| 欧美在线免费| 一区二区视频在线观看| 欧美精品羞羞答答| 欧美xxxx黑人又粗又长密月| 电影一区二区在线观看| 91传媒在线免费观看| 日本中文字幕视频一区| 国产精品久久久久久婷婷天堂| 中文av在线全新| 98视频在线噜噜噜国产| 美女尤物在线视频| 精品综合久久久久久97| 久操视频在线| 久久精品国产久精国产一老狼| eeuss影院在线播放| 亚洲天堂网站在线观看视频| 免费在线黄色影片| 日韩电影免费在线观看中文字幕 | 99久热在线精品视频| 99久久99视频只有精品| 艳色歌舞团一区二区三区| 欧美日韩性在线观看| 欧美日韩综合久久| 亚洲欧美校园春色| 欧美人与性禽动交精品| 中文有码一区| 日韩av图片| 欧美日一区二区| 午夜精品一区二区在线观看| 波多野结衣一区| 亚洲午夜精品久久| 亚洲成av人片一区二区密柚| 青少年xxxxx性开放hg| 婷婷丁香综合| 国产资源第一页| 激情欧美国产欧美| 91九色在线观看视频| 亚洲欧美日韩精品一区二区| 国产免费一区二区三区视频| 日韩国产欧美三级| 少妇一级淫免费播放| 国产精品 欧美精品| 捆绑裸体绳奴bdsm亚洲| 久久综合九色综合欧美就去吻| 欧美成人国产精品一区二区| 中文一区二区在线观看| 亚洲欧美小视频| 亚洲午夜视频在线| 国产黄色免费观看| 欧美日韩一二三区| 国产av精国产传媒| 亚洲精品成人久久电影| 国产二区在线播放| 美女精品视频一区| 欧美男人天堂| 国产精品日日摸夜夜添夜夜av| 国产精品白丝久久av网站| y111111国产精品久久婷婷| 欧美影院天天5g天天爽| 亚洲精品乱码视频| 午夜国产精品视频| 国产性xxxx18免费观看视频| 激情亚洲综合在线| 奇米777第四色| 国产精品理论片| 中文字幕第28页| 精品视频在线免费看| 国产成人av免费看| 亚洲人成在线播放| 欧洲一区二区三区| 国产极品jizzhd欧美| 99久久免费精品国产72精品九九| 欧美成ee人免费视频| 中文字幕免费精品| 日韩精品无码一区二区三区免费| 国产最新精品免费| 99久久人妻无码精品系列| 一区二区三区四区激情| 国产成人自拍偷拍| 精品精品欲导航| 网友自拍视频在线| 91成人免费观看网站| 久久精品一级| 日韩精品成人一区二区在线观看| 伊人成人在线视频| 污免费在线观看| 国产欧美日韩在线看| 黄色激情视频在线观看| 91精品欧美福利在线观看| 韩国中文字幕2020精品| 性欧美长视频免费观看不卡| 粉嫩一区二区三区在线观看| 日本视频一区二区在线观看| 伊人久久亚洲热| 老女人性生活视频| 国产精品黄色在线观看| 中文字幕视频网| 亚洲第一福利网| 色屁屁www国产馆在线观看| 国产一区香蕉久久| 日本不卡电影| 国产精品69页| 久久欧美一区二区| 亚洲精品77777| 欧美精品一区二| 日韩av官网| 91精品国产一区二区三区动漫 | 日韩精品视频在线观看视频 | 亚洲天堂激情| 香蕉视频在线观看黄| 亚洲人吸女人奶水| 国产一区二区麻豆| 日韩一区二区欧美| 日韩毛片在线| 亚洲bbw性色大片| 蜜臀精品久久久久久蜜臀| 欧美福利第一页| 在线观看一区不卡| 国产高清免费av在线| 国产精品免费小视频| 精品视频日韩| 天堂网在线免费观看| 国产精品久久久久影院亚瑟 | 韩国一区二区视频| 黄色a级片在线观看| 欧美电影影音先锋| 久久久久久久久免费视频| 成人h片在线播放免费网站| 99久久影视| 亚洲视频在线不卡| 亚洲一区二区三区四区在线免费观看 | 国产一区二区看久久| 欧美色图亚洲天堂| 亚洲国产黄色片| 悠悠资源网亚洲青| 日韩中文字幕一区二区| 麻豆精品视频在线观看视频| 国产中文字幕久久| 91精品婷婷国产综合久久性色| 91福利国产在线观看菠萝蜜| 97人人干人人| 亚洲全部视频| 欧美多人猛交狂配| 欧美老人xxxx18| 人人超在线公开视频| 久久久久成人精品免费播放动漫| 天堂久久一区二区三区| 欧美性生给视频| 日韩美女主播在线视频一区二区三区 | 一区三区在线欧| 蜜臀一区二区三区精品免费视频| 亚洲欧美经典视频| 天堂av2024| 国产精品久久久久av免费| 久久久久久久久久久9不雅视频 | 欧美午夜在线播放| 精品无码国模私拍视频| 日本一区二区三区久久久久久久久不 | 777奇米四色成人影色区| 久久一卡二卡| 欧美日韩一区二区视频在线观看| 久色婷婷小香蕉久久| 国产在线综合网| 亚洲人a成www在线影院| 精品一区91| 别急慢慢来1978如如2| 亚洲欧美国产毛片在线| 三级在线电影| 亚洲专区在线视频| 亚洲一区国产| 欧美大片xxxx| 日韩久久午夜影院| 99精品女人在线观看免费视频| 人妻夜夜添夜夜无码av| 亚洲国产精品成人综合| 国产成人手机在线| 国产精品美女在线观看| 亚洲国产清纯| 日韩一级片av| 色妞在线综合亚洲欧美|