国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Vue.nextTick 的原理和用途

fevin / 1998人閱讀

摘要:在查詢了各種資料后,總結(jié)了一下其原理和用途,如有錯(cuò)誤,請不吝賜教。截取關(guān)鍵部分如下具體來說,異步執(zhí)行的運(yùn)行機(jī)制如下。知乎上的例子改變數(shù)據(jù)想要立即使用更新后的。需要注意的是,在和階段,如果需要操作渲染后的試圖,也要使用方法。

對于 Vue.nextTick 方法,自己有些疑惑。在查詢了各種資料后,總結(jié)了一下其原理和用途,如有錯(cuò)誤,請不吝賜教。
概覽
官方文檔說明:

用法:

在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后立即使用這個(gè)方法,獲取更新后的 DOM。

疑問:

DOM 更新循環(huán)是指什么?

下次更新循環(huán)是什么時(shí)候?

修改數(shù)據(jù)之后使用,是加快了數(shù)據(jù)更新進(jìn)度嗎?

在什么情況下要用到?

原理 異步說明
Vue 實(shí)現(xiàn)響應(yīng)式并不是數(shù)據(jù)發(fā)生變化之后 DOM 立即變化,而是按一定的策略進(jìn)行 DOM 的更新。

在 Vue 的文檔中,說明 Vue 是異步執(zhí)行 DOM 更新的。關(guān)于異步的解析,可以查看阮一峰老師的這篇文章。截取關(guān)鍵部分如下:

具體來說,異步執(zhí)行的運(yùn)行機(jī)制如下。

(1)所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack)。
(2)主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"(task queue)。只要異步任務(wù)有了運(yùn)行結(jié)果,就在"任務(wù)隊(duì)列"之中放置一個(gè)事件。
(3)一旦"執(zhí)行棧"中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取"任務(wù)隊(duì)列",看看里面有哪些事件。那些對應(yīng)的異步任務(wù),于是結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行。
(4)主線程不斷重復(fù)上面的第三步。

下圖就是主線程和任務(wù)隊(duì)列的示意圖。

事件循環(huán)說明

簡單來說,Vue 在修改數(shù)據(jù)后,視圖不會(huì)立刻更新,而是等同一事件循環(huán)中的所有數(shù)據(jù)變化完成之后,再統(tǒng)一進(jìn)行視圖更新。

知乎上的例子:

//改變數(shù)據(jù)
vm.message = "changed"

//想要立即使用更新后的DOM。這樣不行,因?yàn)樵O(shè)置message后DOM還沒有更新
console.log(vm.$el.textContent) // 并不會(huì)得到"changed"

//這樣可以,nextTick里面的代碼會(huì)在DOM更新后執(zhí)行
Vue.nextTick(function(){
    console.log(vm.$el.textContent) //可以得到"changed"
})

圖解:

事件循環(huán):

第一個(gè) tick(圖例中第一個(gè)步驟,即"本次更新循環(huán)"):

首先修改數(shù)據(jù),這是同步任務(wù)。同一事件循環(huán)的所有的同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧,此時(shí)還未涉及 DOM 。

Vue 開啟一個(gè)異步隊(duì)列,并緩沖在此事件循環(huán)中發(fā)生的所有數(shù)據(jù)改變。如果同一個(gè) watcher 被多次觸發(fā),只會(huì)被推入到隊(duì)列中一次。

第二個(gè) tick(圖例中第二個(gè)步驟,即"下次更新循環(huán)"):

同步任務(wù)執(zhí)行完畢,開始執(zhí)行異步 watcher 隊(duì)列的任務(wù),更新 DOM 。Vue 在內(nèi)部嘗試對異步隊(duì)列使用原生的 Promise.then 和 MessageChannel 方法,如果執(zhí)行環(huán)境不支持,會(huì)采用 setTimeout(fn, 0) 代替。

第三個(gè) tick(圖例中第三個(gè)步驟):

此時(shí)就是文檔所說的

下次 DOM 更新循環(huán)結(jié)束之后

此時(shí)通過 Vue.nextTick 獲取到改變后的 DOM 。通過 setTimeout(fn, 0) 也可以同樣獲取到。

簡單總結(jié)事件循環(huán):

同步代碼執(zhí)行 -> 查找異步隊(duì)列,推入執(zhí)行棧,執(zhí)行Vue.nextTick[事件循環(huán)1] ->查找異步隊(duì)列,推入執(zhí)行棧,執(zhí)行Vue.nextTick[事件循環(huán)2]...

總之,異步是多帶帶的一個(gè)tick,不會(huì)和同步在一個(gè) tick 里發(fā)生,也是 DOM 不會(huì)馬上改變的原因。

對于事件循環(huán),可以在這里查看更詳細(xì)的內(nèi)容: https://segmentfault.com/a/11...
用途
應(yīng)用場景:需要在視圖更新之后,基于新的視圖進(jìn)行操作。
created、mounted

需要注意的是,在 created 和 mounted 階段,如果需要操作渲染后的試圖,也要使用 nextTick 方法。

官方文檔說明:

注意 mounted 不會(huì)承諾所有的子組件也都一起被掛載。如果你希望等到整個(gè)視圖都渲染完畢,可以用 vm.$nextTick 替換掉 mounted
mounted: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}
其他應(yīng)用場景

其他應(yīng)用場景如下三例:

例子1:

點(diǎn)擊按鈕顯示原本以 v-show = false 隱藏起來的輸入框,并獲取焦點(diǎn)。

showsou(){
  this.showit = true //修改 v-show
  document.getElementById("keywords").focus()  //在第一個(gè) tick 里,獲取不到輸入框,自然也獲取不到焦點(diǎn)
}

修改為:

showsou(){
  this.showit = true
  this.$nextTick(function () {
    // DOM 更新了
    document.getElementById("keywords").focus()
  })
}

例子2:

點(diǎn)擊獲取元素寬度。

{{ message }}

getMyWidth() { this.showMe = true; //this.message = this.$refs.myWidth.offsetWidth; //報(bào)錯(cuò) TypeError: this.$refs.myWidth is undefined this.$nextTick(()=>{ //dom元素更新后執(zhí)行,此時(shí)能拿到p元素的屬性 this.message = this.$refs.myWidth.offsetWidth; }) }

例子3:

使用 swiper 插件通過 ajax 請求圖片后的滑動(dòng)問題。

實(shí)例理解 nextTick 應(yīng)用

下面的例子來自 https://www.cnblogs.com/hity-..., 稍有改動(dòng)。各位可以復(fù)制運(yùn)行一遍,加深理解。


結(jié)果:

參考文章

vue nextTick深入理解-vue性能優(yōu)化、DOM更新時(shí)機(jī)、事件循環(huán)機(jī)制;
JavaScript 運(yùn)行機(jī)制詳解:再談Event Loop
知乎:vue.js$nextTick的一個(gè)問題
JS 事件循環(huán)機(jī)制 - 任務(wù)隊(duì)列、web API、JS主線程的相互協(xié)同

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/92525.html

相關(guān)文章

  • Vue.nextTick淺析

    摘要:淺析的特點(diǎn)之一就是響應(yīng)式,但數(shù)據(jù)更新時(shí),并不會(huì)立即更新。盡管已經(jīng)更新,但新增的元素并不立即插入到中。實(shí)際在中,執(zhí)行了,這也是自動(dòng)綁定到執(zhí)行上下文的原因。在內(nèi),使用數(shù)組保存回調(diào)函數(shù),表示當(dāng)前狀態(tài),使用函數(shù)來執(zhí)行回調(diào)隊(duì)列。 Vue.nextTick 淺析 Vue 的特點(diǎn)之一就是響應(yīng)式,但數(shù)據(jù)更新時(shí),DOM 并不會(huì)立即更新。當(dāng)我們有一個(gè)業(yè)務(wù)場景,需要在 DOM 更新之后再執(zhí)行一段代碼時(shí),可以...

    MartinDai 評論0 收藏0
  • Vue原理NextTick - 源碼版 之 獨(dú)立自身

    摘要:盡量把所有異步代碼放在一個(gè)宏微任務(wù)中,減少消耗加快異步代碼的執(zhí)行。我們知道,如果一個(gè)異步代碼就注冊一個(gè)宏微任務(wù)的話,那么執(zhí)行完全部異步代碼肯定慢很多避免頻繁地更新。中就算我們一次性修改多次數(shù)據(jù),頁面還是只會(huì)更新一次。 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5...

    劉東 評論0 收藏0
  • Vue原理NextTick - 源碼版 之 宏微任務(wù)抉擇

    摘要:這么講,有點(diǎn)籠統(tǒng),準(zhǔn)確地說,應(yīng)該是事件回調(diào)執(zhí)行過程中,在主線程為空之后,異步代碼執(zhí)行之前,所有通過注冊的異步代碼都是用宏任務(wù)。 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧 【...

    raise_yang 評論0 收藏0
  • Vue.nextTick使用源碼分析

    摘要:而中的回調(diào)函數(shù)則會(huì)在頁面渲染后才執(zhí)行。還使用方法復(fù)制數(shù)組并把數(shù)組清空,這里的數(shù)組就是存放主線程執(zhí)行過程中的函數(shù)所傳的回調(diào)函數(shù)集合主線程可能會(huì)多次使用方法。到這里就已經(jīng)實(shí)現(xiàn)了根據(jù)環(huán)境選擇異步方法,并在異步方法中依次調(diào)用傳入方法的回調(diào)函數(shù)。 Vue.nextTick的應(yīng)用場景 Vue 是采用異步的方式執(zhí)行 DOM 更新。只要觀察到數(shù)據(jù)變化,Vue 將開啟一個(gè)隊(duì)列,并緩沖同一事件循環(huán)中發(fā)生的...

    Jrain 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<