亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Vue異步更新DOM及$nextTick執(zhí)行機(jī)制解讀

 更新時(shí)間:2023年03月24日 09:59:07   作者:shangdong2023  
這篇文章主要介紹了Vue異步更新DOM及$nextTick執(zhí)行機(jī)制解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Vue異步更新DOM策略

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

Vue 在更新 DOM 時(shí)是異步執(zhí)行的。只要偵聽到數(shù)據(jù)變化,Vue 將開啟一個(gè)隊(duì)列,并緩沖在同一事件循環(huán)中發(fā)生的所有數(shù)據(jù)變更。如果同一個(gè) watcher 被多次觸發(fā),只會(huì)被推入到隊(duì)列中一次。這種在緩沖時(shí)去除重復(fù)數(shù)據(jù)對(duì)于避免不必要的計(jì)算和 DOM 操作是非常重要的。然后,在下一個(gè)的事件循環(huán) “tick" 中,Vue 刷新隊(duì)列并執(zhí)行實(shí)際(已去重的)工作。

$nextTick執(zhí)行機(jī)制

$nextTick會(huì)在DOM更新之后被觸發(fā),以獲取最新DOM節(jié)點(diǎn)。

具體來(lái)講:我們使用 JavaScript 進(jìn)行原生DOM操作時(shí),隨著 JavaScript 代碼執(zhí)行會(huì)同步進(jìn)行DOM更新;而使用 Vue 則會(huì)異步更新 DOM,會(huì)在當(dāng)前執(zhí)行棧的最后更新DOM。

對(duì)于兼容的瀏覽器來(lái)說(shuō),nextTick相當(dāng)于是微任務(wù),即$nextTick的回調(diào)函數(shù)是在當(dāng)前執(zhí)行棧的所有同步任務(wù)執(zhí)行完畢后再執(zhí)行,所以nextTick中會(huì)得到 DOM 更新后的結(jié)果。(不過頁(yè)面渲染始終是在微任務(wù)執(zhí)行之后才進(jìn)行的,所以$nextTick回調(diào)函數(shù)執(zhí)行時(shí)頁(yè)面還沒有進(jìn)行渲染,回調(diào)函數(shù)執(zhí)行時(shí)在頁(yè)面上看不到更新后的結(jié)果)

注:瀏覽器如果不兼容則有幾種備選方案,其中setTimeout是最后的一種備選方案,它會(huì)將回調(diào)函數(shù)加入任務(wù)隊(duì)列 task 中,等待執(zhí)行。

示例詳解

JavaScript原生DOM操作(隨著JS代碼的執(zhí)行同步進(jìn)行DOM更新):

<body>
? ? <ul id="ul1">
? ? ? ? <li>100</li>
? ? ? ? <li>200</li>
? ? ? ? <li>300</li>
? ? </ul>

? ? <script>
? ? ? ? const ul1 = document.getElementById('ul1')
? ? ? ? console.log(ul1.children.length); // 3
? ? ? ? const newLi = document.createElement('li')
? ? ? ? newLi.innerHTML = '400'
? ? ? ? ul1.appendChild(newLi)
? ? ? ? console.log(ul1.children.length); // 4
? ? ? ? Promise.resolve().then(() => {
? ? ? ? ? ? alert(ul1.children.length) // 彈出4,此時(shí)頁(yè)面還沒有進(jìn)行渲染(頁(yè)面還未展示內(nèi)容)
? ? ? ? })
? ? </script>
</body>

Vue異步更新DOM:

<template>
? <div id="app">
? ? <ul ref="ul1">
? ? ? <li v-for="(item, index) in list" :key="index">
? ? ? ? {{ item }}
? ? ? </li>
? ? </ul>
? ? <button @click="addItem">添加一項(xiàng)</button>
? </div>
</template>

<script>
export default {
? name: "app",
? data() {
? ? return {
? ? ? list: ["a", "b", "c"],
? ? };
? },
? methods: {
? ? addItem() {
? ? ? this.list.push(`${Date.now()}`);
? ? ? this.list.push(`${Date.now()}`);
? ? ? this.list.push(`${Date.now()}`);

? ? ? // 獲取 DOM 元素
? ? ? const ulElem = this.$refs.ul1;
? ? ? // eslint-disable-next-line
? ? ? console.log(ulElem.childNodes.length);// 3

? ? ? // 1. 異步進(jìn)行 dom 更新,$nextTick 待 DOM 更新完再回調(diào)
? ? ? // 2. dom 更新時(shí)會(huì)將 data 的修改做整合,多次 data 修改只會(huì)更新一次
? ? ? this.$nextTick(() => {
? ? ? ? // eslint-disable-next-line
? ? ? ? console.log(ulElem.childNodes.length); // 6

? ? ? ? alert(ulElem.childNodes.length); // 彈出 6,此時(shí)頁(yè)面還沒有進(jìn)行渲染(頁(yè)面還沒展示新添加的3個(gè)元素)
? ? ? });
? ? },
? },
};
</script>

Vue異步更新DOM的目的

因?yàn)槿绻竭M(jìn)行DOM更新,則每次對(duì)響應(yīng)式數(shù)據(jù)進(jìn)行修改就都會(huì)觸發(fā)setter -> 通知watcher -> 觸發(fā)re-render -> 生成new vnode(vdom) -> patch(更新真實(shí)DOM)。

如果每次修改數(shù)據(jù)都會(huì)走一遍這個(gè)流程是非常消耗性能的,所以使用異步更新 DOM 的策略,先對(duì)數(shù)據(jù)修改進(jìn)行整合,再使用最終的整合結(jié)果一次性對(duì) DOM 進(jìn)行更新。

$nextTick應(yīng)用示例

<template>
? <div>
? ? <button @click="callbackFun">點(diǎn)我展示輸入框并自動(dòng)獲取焦點(diǎn)</button> <br />
? ? <input type="text" v-show="test" ref="input" />
? </div>
</template>

<script>
export default {
? name: "App",
? data() {
? ? return {
? ? ? test: false,
? ? };
? },
? methods: {
? ? callbackFun() {
? ? ? this.test = true;
? ? ? this.$nextTick(function () {
? ? ? ? this.$refs.input.focus(); // 若該行代碼不放在 $nextTick 中,則無(wú)法展示輸入框后自動(dòng)獲取焦點(diǎn)
? ? ? });
? ? },
? },
};
</script>

總結(jié)

以上代碼,因?yàn)閷@取焦點(diǎn)的代碼放入$nextTick的回調(diào)函數(shù)中執(zhí)行,所以點(diǎn)擊button后會(huì)展示已經(jīng)獲取到焦點(diǎn)的輸入框。

希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue實(shí)現(xiàn)可以快進(jìn)后退的跑馬燈組件

    vue實(shí)現(xiàn)可以快進(jìn)后退的跑馬燈組件

    這篇文章主要為大家詳細(xì)介紹了vue編寫一個(gè)可以快進(jìn)后退的跑馬燈組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 記錄vue做微信自定義分享的一些問題

    記錄vue做微信自定義分享的一些問題

    這篇文章主要介紹了記錄vue做微信自定義分享的一些問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Vue v2.5 調(diào)整和更新不完全問題

    Vue v2.5 調(diào)整和更新不完全問題

    這篇文章主要介紹了Vue v2.5 調(diào)整和更新不完全問題的相關(guān)資料,需要的朋友可以參考下
    2017-10-10
  • 解決vue-cli + webpack 新建項(xiàng)目出錯(cuò)的問題

    解決vue-cli + webpack 新建項(xiàng)目出錯(cuò)的問題

    下面小編就為大家分享一篇解決vue-cli + webpack 新建項(xiàng)目出錯(cuò)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2018-03-03
  • vue利用openlayers加載天地圖和高德地圖

    vue利用openlayers加載天地圖和高德地圖

    這篇文章主要介紹了?vue利用openlayers加載天地圖和高德地圖,下文章主要由兩部分完成openlayers加載天地圖和加載高德地圖,下面來(lái)看看詳細(xì)內(nèi)容吧,需要的朋友可以參考一下,希望對(duì)大家有所幫助
    2021-11-11
  • vue3全局導(dǎo)入bootstrap5方式

    vue3全局導(dǎo)入bootstrap5方式

    這篇文章主要介紹了vue3全局導(dǎo)入bootstrap5方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • vue electron應(yīng)用調(diào)exe程序的實(shí)現(xiàn)步驟

    vue electron應(yīng)用調(diào)exe程序的實(shí)現(xiàn)步驟

    這篇文章主要介紹了vue electron應(yīng)用調(diào)exe程序的實(shí)現(xiàn)步驟,用Python寫了一個(gè)本地服務(wù)編譯成exe程序,在electron程序啟動(dòng)后,自動(dòng)執(zhí)行exe程序,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2024-02-02
  • vue實(shí)現(xiàn)選項(xiàng)卡小案例

    vue實(shí)現(xiàn)選項(xiàng)卡小案例

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)選項(xiàng)卡小案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • vue?this.$router六種方法使用示例總結(jié)分析

    vue?this.$router六種方法使用示例總結(jié)分析

    這篇文章主要為大家介紹了vue this.$router六種方法使用示例總結(jié)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • elementUI給el-tabs/el-tab-pane添加圖標(biāo)效果實(shí)例

    elementUI給el-tabs/el-tab-pane添加圖標(biāo)效果實(shí)例

    這篇文章主要給大家介紹了關(guān)于elementUI給el-tabs/el-tab-pane添加圖標(biāo)效果實(shí)例的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用elementUI具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-07-07

最新評(píng)論