日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

解析$nextTick魔力,為啥大家都愛它?

來源: 責編: 時間:2024-01-02 09:31:13 205觀看
導讀1.為什么需要使用$nextTick?首先我們來看看官方對于$nextTick的定義:在下次 DOM 更新循環結束之后執行延遲回調。在修改數據之后立即使用這個方法,獲取更新后的 DOM。由于vue的試圖渲染是異步的,生命周期的created()鉤

1.為什么需要使用$nextTick?

首先我們來看看官方對于$nextTick的定義:6qv28資訊網——每日最新資訊28at.com

在下次 DOM 更新循環結束之后執行延遲回調。在修改數據之后立即使用這個方法,獲取更新后的 DOM。6qv28資訊網——每日最新資訊28at.com

由于vue的試圖渲染是異步的,生命周期的created()鉤子函數進行的DOM操作一定要放在Vue.nextTick()的回調函數中,原因是在created()鉤子函數執行的時候DOM其實并未進行渲染,而此時進行DOM操作是徒勞的,所以一定要將DOM操作的js代碼放到Vue.nextTick()的回調函數中。除了在created()鉤子函數中使用之外咱們還會遇到很多種需要使用到Vue.nextTick()的場景,如下所示:6qv28資訊網——每日最新資訊28at.com

咱們日常生活中常常會遇上上述場景,當我們點擊按鈕更新數據時候,如下示例:6qv28資訊網——每日最新資訊28at.com

<template>    <div>     <input type="text" v-if = "isShow" ref="input"/>     <button @click="handleClick">點擊顯示輸入框,并且獲取輸入框焦點</button>   </div></template><script>export default { data() {     return {         isShow: false       } }, methods : { handleClick () {     this.isShow = true     this.$refs.input.focus() //控制欄會報錯,因為還沒有這個dom        }  }}</script>

點擊控制欄顯示效果:控制欄報錯,提示沒有獲取到dom元素;6qv28資訊網——每日最新資訊28at.com

6qv28資訊網——每日最新資訊28at.com

所以現在Vue.nextTick()派上了用場,Vue.nextTick() 方法的作用正是等待上一次事件循環執行完畢,并在下一次事件循環開始時再執行回調函數。這樣可以保證回調函數中的 DOM 操作已經被 Vue.js 進行過更新,從而避免了一些潛在的問題,如下代碼所示:6qv28資訊網——每日最新資訊28at.com

<template>  <div>    <input type="text" v-if = "isShow" ref="input"/>    <button @click="handleClick">點擊顯示輸入框,并且獲取輸入框焦點</button>  </div></template><script>export default { data() {   return {     isShow: false   } }, methods : {   handleClick () {     this.isShow = true     this.$nextTick(()=>{       this.$refs.input.focus()      })    } }}</script>

加上this.$nextTick后就能夠使得輸入框獲取到焦點;6qv28資訊網——每日最新資訊28at.com

總而言之Vue.nextTick()就是下次 DOM 更新渲染后執行延遲回調函數。在日常開發中,我們在修改數據之后使用這個方法,就可以獲取更新后的 DOM的同時進行在對DOM進行相對應操作的 js代碼;6qv28資訊網——每日最新資訊28at.com

2.$nextTick如何實現的?

JS是單線程執行的,所有的同步任務都是在主線程上執行的,形成了一個執行棧,從上到下依次執行,異步代碼會放在任務隊列里面。6qv28資訊網——每日最新資訊28at.com

?同步任務6qv28資訊網——每日最新資訊28at.com

在主線程里執行,當瀏覽器第一遍過濾html文件的時候可以執行完;(在當前作用域直接執行的所有內容,包括執行的方法、new出來的對象)6qv28資訊網——每日最新資訊28at.com

?異步任務6qv28資訊網——每日最新資訊28at.com

耗費時間較長或者性能較差的,瀏覽器執行到這些的時候會將其丟到異步任務隊列中,不會立即執行6qv28資訊網——每日最新資訊28at.com

同時異步任務分為宏任務(如setTimeout、setInterval、postMessage、setImmediate等)和微任務(Promise、process.nextTick等),瀏覽器執行這兩種任務的優先級不同;會優先執行微任務隊列的代碼,微任務隊列清空之后再執行宏任務的隊列,這樣循環往復;6qv28資訊網——每日最新資訊28at.com

JS自上向下進行代碼的編譯執行,遇到同步代碼壓入JS執行棧執行后出棧,遇到異步代碼放入任務隊列,當JS執行棧清空,去執行異步隊列中的回調函數,先去執行微任務隊列,當微任務隊列清空后,去檢測執行宏任務隊列中的回調函數,直至所有棧和隊列清空6qv28資訊網——每日最新資訊28at.com

整體流程如下圖所示:6qv28資訊網——每日最新資訊28at.com

6qv28資訊網——每日最新資訊28at.com

6qv28資訊網——每日最新資訊28at.com

6qv28資訊網——每日最新資訊28at.com

接下來讓我們看看nextTick的源碼~6qv28資訊網——每日最新資訊28at.com

vue將nextTick的源碼放在了vue/core/util/next-tick.js中。如下圖所示:6qv28資訊網——每日最新資訊28at.com

6qv28資訊網——每日最新資訊28at.com

6qv28資訊網——每日最新資訊28at.com

我們把這個文件拆成三個部分來看:6qv28資訊網——每日最新資訊28at.com

1.nextTick定義函數

我們將nextTick函數單獨拿出來,callbacks是一個回調隊列,其實調用nextTick就是往這個數組里面傳執行任務,callbacks新增回調函數之后執行timerFunc函數,pending是用來限制同一個事件循環內只能執行一次的pending鎖;6qv28資訊網——每日最新資訊28at.com

const callbacks = [] // 回調隊列let pending = false // export function nextTick (cb?: Function, ctx?: Object) { let _resolve callbacks.push(() => {  // cb 回調函數會經統一處理壓入 callbacks 數組     if (cb) {         try {             cb.call(ctx)         } catch (e) {             handleError(e, ctx, 'nextTick')         }     } else if (_resolve) {         _resolve(ctx)        }     })  // 執行異步延遲函數 timerFunc     if (!pending) {     pending = true     timerFunc() } // $flow-disable-line // 當 nextTick 沒有傳入函數參數的時候,返回一個 Promise 化的調用if (!cb && typeof Promise !== 'undefined') {     return new Promise(resolve => {     _resolve = resolve     }) }}

2.timerFunc函數

 做了四個判斷,先后嘗試當前環境是否能夠使用原生的Promise.then、MutationObserver和setImmediate,不斷的降級處理,如果以上三個都不支持,則最后就會直接使用setTimeOut,主要操作就是將flushCallbacks中的函數放入微任務或者宏任務,等待下一個事件循環開始執行;宏任務耗費的時間是大于微任務的,所以在瀏覽器支持的情況下,優先使用微任務。如果瀏覽器不支持微任務,使用宏任務;但是,各種宏任務之間也有效率的不同,需要根據瀏覽器的支持情況,使用不同的宏任務;6qv28資訊網——每日最新資訊28at.com

export let isUsingMicroTask = falselet timerFuncif (typeof Promise !== 'undefined' && isNative(Promise)) { //是否支持Promise const p = Promise.resolve() timerFunc = () => { p.then(flushCallbacks)  if (isIOS) setTimeout(noop) } isUsingMicroTask = true} else if (!isIE && typeof MutationObserver !== 'undefined' && ( isNative(MutationObserver) || MutationObserver.toString() === '[object MutationObserverConstructor]')) {//是否支持MutationObserver  let counter = 1 const observer = new MutationObserver(flushCallbacks) const textNode = document.createTextNode(String(counter)) observer.observe(textNode, { characterData: true }) timerFunc = () => { counter = (counter + 1) % 2 textNode.data = String(counter) } isUsingMicroTask = true} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) { timerFunc = () => {  //是否支持setImmediate setImmediate(flushCallbacks) }} else { // Fallback to setTimeout. timerFunc = () => {  //上面都不行,直接使用setTimeout setTimeout(flushCallbacks, 0) }}

3.flushCallbacks函數

flushCallbacks函數只有幾行,也很好理解,將pending鎖置為false,同時將callbacks數組復制一份之后再將callbacks置為空,接下來將復制出來的callbacks數組的每個函數依次進行執行,簡單來說它的主要作用就是用來執行callbacks中的回調函數;6qv28資訊網——每日最新資訊28at.com

function flushCallbacks () { pending = false const copies = callbacks.slice(0) callbacks.length = 0 for (let i = 0; i < copies.length; i++) {     copies[i]() }}

值得注意的是,$nextTick 并不是一個真正意義上的微任務microtask,而是利用了事件循環機制來實現異步更新。因此,它的執行時機相對于微任務可能會有所延遲,但仍能保證在 DOM 更新后盡快執行回調函數。6qv28資訊網——每日最新資訊28at.com

總的來說,nextTick就是6qv28資訊網——每日最新資訊28at.com

1.將傳入的回調函數放入callbacks數組等待執行,定義pending判斷鎖保證一個事件循環中只能調用一次timerFunc函數;6qv28資訊網——每日最新資訊28at.com

2.根據環境判斷使用異步方式,調用timerFunc函數調用flushCallbacks函數依次執行callbacks中的回調函數;6qv28資訊網——每日最新資訊28at.com

3.個人小結

nextTick可避免數據更新后導致DOM的數據不一致的問題,提供了更穩定的異步更新機制,解決了created鉤子函數DOM未渲染會造成的異步數據渲染問題,但如果過多的使用nextTick會導致事件循環中任務數量和回調函數增多,有可能出現可怕的回調地獄,導致性能下降,同時過度依賴nextTick也會降低代碼的可讀性,所以大家還是"按需加載"的好~6qv28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-55184-0.html解析$nextTick魔力,為啥大家都愛它?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 沒有煩惱的Saga

下一篇: 解析$nextTick魔力,為啥大家都愛它?

標簽:
  • 熱門焦點
  • vivo TWS Air開箱體驗:真輕 臻好聽

    在vivo S15系列新機的發布會上,vivo的最新款真無線藍牙耳機vivo TWS Air也一同發布,本次就這款耳機新品給大家帶來一個簡單的分享。外包裝盒上,vivo TWS Air保持了vivo自家產
  • 一文掌握 Golang 模糊測試(Fuzz Testing)

    模糊測試(Fuzz Testing)模糊測試(Fuzz Testing)是通過向目標系統提供非預期的輸入并監視異常結果來發現軟件漏洞的方法。可以用來發現應用程序、操作系統和網絡協議等中的漏洞或
  • 一文搞定Java NIO,以及各種奇葩流

    大家好,我是哪吒。很多朋友問我,如何才能學好IO流,對各種流的概念,云里霧里的,不求甚解。用到的時候,現百度,功能雖然實現了,但是為什么用這個?不知道。更別說效率問題了~下次再遇到,
  • 破圈是B站頭上的緊箍咒

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之每年的暑期檔都少不了瞄準追劇女孩們的古偶劇集,2021年有優酷的《山河令》,2022年有愛奇藝的《蒼蘭訣》,今年卻輪到小破站抓住了追
  • 2納米決戰2025

    集微網報道 從三強爭霸到四雄逐鹿,2nm的廝殺聲已然隱約傳來。無論是老牌勁旅臺積電、三星,還是誓言重回先進制程領先地位的英特爾,甚至初成立不久的新
  • 三星折疊屏手機去年銷售近1000萬臺 今年目標定為1500萬

    7月29日消息,三星率先發力可折疊手機市場,在全球市場已經取得了非常亮眼的成績,接下來會進一步鞏固和擴大這一優勢。三星在推出Galaxy Z Flip5和Galax
  • SN570 NVMe SSD固態硬盤 價格與性能兼具

    SN570 NVMe SSD固態硬盤是西部數據發布的最新一代WD Blue系列的固態硬盤,不僅閃存技術更為精進,性能也得到了進一步的躍升。WD Blue SN570 NVMe SSD的包裝外
  • 英特爾Xe HPG游戲顯卡:擁有512EU,單風扇版本

    據10 月 30 日外媒 TheVerge 消息報道,英特爾 Xe HPG Arc Alchemist 的正面實被曝光,不僅擁有 512 EU 版顯卡,還擁有 128EU 的單風扇版本。另外,這款顯卡 PCB
  • “買真退假” 這種“羊毛”不能薅

    □ 法治日報 記者 王春   □ 本報通訊員 胡佳麗  2020年初,還在上大學的小東加入了一個大學生兼職QQ群。群主&ldquo;七王&rdquo;在群里介紹一些刷單賺
Top 主站蜘蛛池模板: 都匀市| 宜君县| 安阳市| 柳林县| 太和县| 布尔津县| 嘉善县| 翁牛特旗| 军事| 区。| 云和县| 博野县| 康定县| 新化县| 通辽市| 玉树县| 阿尔山市| 南安市| 剑阁县| 黎城县| 卓资县| 随州市| 锦屏县| 石景山区| 九江县| 炎陵县| 大洼县| 乌苏市| 久治县| 来凤县| 长岭县| 新密市| 邵武市| 昌江| 鄢陵县| 西青区| 金华市| 崇礼县| 寻乌县| 英德市| 屏东县|