欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue的狀態(tài)更新方式(異步更新解決)

 更新時(shí)間:2022年04月19日 09:00:53   作者:李弈圣  
這篇文章主要介紹了vue的狀態(tài)更新方式(異步更新解決),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

狀態(tài)更新(異步更新解決)

在vue中狀態(tài)更新是異步的,這一點(diǎn)和react中的setstate類似。

解決方案

非組件解決方案:

<div id="example">{{message}}</div>
var vm = new Vue({
? el: '#example',
? data: {
? ? message: '123'
? }
})
vm.message = 'new message' // 更改數(shù)據(jù)
vm.$el.textContent === 'new message' // false
Vue.nextTick(function () {
? vm.$el.textContent === 'new message' // true
})

在組件內(nèi)使用 vm.$nextTick() 實(shí)例方法特別方便,因?yàn)樗恍枰?Vue ,并且回調(diào)函數(shù)中的 this 將自動(dòng)綁定到當(dāng)前的 Vue 實(shí)例上:

Vue.component('example', {
? template: '<span>{{ message }}</span>',
? data: function () {
? ? return {
? ? ? message: '沒有更新'
? ? }
? },
? methods: {
? ? updateMessage: function () {
? ? ? this.message = '更新完成'
? ? ? console.log(this.$el.textContent) // => '沒有更新'
? ? ? this.$nextTick(function () {
? ? ? ? console.log(this.$el.textContent) // => '更新完成'
? ? ? })
? ? }
? }
})

因?yàn)?$nextTick() 返回一個(gè) Promise 對(duì)象,所以你可以使用新的 ES2016 async/await 語法完成相同的事情:methods: {

? updateMessage: async function () {
? ? this.message = 'updated'
? ? console.log(this.$el.textContent) // => '未更新'
? ? await this.$nextTick()
? ? console.log(this.$el.textContent) // => '已更新'
? }
}

異步更新及nexttick

為什么需要異步更新

vue為了避免頻繁的操作DOM,采用異步的方式更新DOM。這些異步操作會(huì)通過nextTick函數(shù)將這些操作以cb的形式放到任務(wù)隊(duì)列中(以微任務(wù)優(yōu)先),當(dāng)每次tick結(jié)束之后就會(huì)去執(zhí)行這些cb,更新DOM。

異步更新內(nèi)部是最重要的就是nextTick方法,它負(fù)責(zé)將異步任務(wù)加入隊(duì)列和執(zhí)行異步任務(wù)。VUE 也將它暴露出來提供給用戶使用。在數(shù)據(jù)修改完成后,立即獲取相關(guān)DOM還沒那么快更新,使用nextTick便可以解決這一問題。

nextTick 原理

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

/*存放異步執(zhí)行的回調(diào)*/
const callbacks = [] 
/*一個(gè)標(biāo)記位,如果已經(jīng)有timerFunc被推送到任務(wù)隊(duì)列中去則不需要重復(fù)推送*/
let pending = false
/*一個(gè)函數(shù)指針,指向函數(shù)將被推送到任務(wù)隊(duì)列中,等到主線程任務(wù)執(zhí)行完時(shí),任務(wù)隊(duì)列中的timerFunc被調(diào)用*/
let timerFunc

/*
  推送到隊(duì)列中下一個(gè)tick時(shí)執(zhí)行
  cb 回調(diào)函數(shù)
  ctx 上下文
*/
export function nextTick (cb?: Function, ctx?: Object) {
  let _resolve
   // 第一步 傳入的cb會(huì)被push進(jìn)callbacks中存放起來
  callbacks.push(() => {
    if (cb) {      
        try {
            cb.call(ctx)
      } catch (e) {
        handleError(e, ctx, 'nextTick')
      }
    } else if (_resolve) {
      _resolve(ctx)
    }
  })  
  // 檢查上一個(gè)異步任務(wù)隊(duì)列(即名為callbacks的任務(wù)數(shù)組)是否派發(fā)和執(zhí)行完畢了。pending此處相當(dāng)于一個(gè)鎖
  if (!pending) {
  // 若上一個(gè)異步任務(wù)隊(duì)列已經(jīng)執(zhí)行完畢,則將pending設(shè)定為true(把鎖鎖上)
    pending = true
    // 調(diào)用判斷Promise,MutationObserver,setTimeout的優(yōu)先級(jí)
    timerFunc()
  }
  // 第三步執(zhí)行返回的狀態(tài)
  if (!cb && typeof Promise !== 'undefined') {   
    return new Promise(resolve => {
      _resolve = resolve
    })
  }
}

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í)際 (已去重的) 工作。

Vue 在內(nèi)部對(duì)異步隊(duì)列嘗試使用原生的 Promise.then、MutationObserver 和 setImmediate,如果執(zhí)行環(huán)境不支持,則會(huì)采用 setTimeout(fn, 0) 代替。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解決vue-cli單頁面手機(jī)應(yīng)用input點(diǎn)擊手機(jī)端虛擬鍵盤彈出蓋住input問題

    解決vue-cli單頁面手機(jī)應(yīng)用input點(diǎn)擊手機(jī)端虛擬鍵盤彈出蓋住input問題

    今天小編就為大家分享一篇解決vue-cli單頁面手機(jī)應(yīng)用input點(diǎn)擊手機(jī)端虛擬鍵盤彈出蓋住input問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • Vue數(shù)據(jù)代理的實(shí)現(xiàn)流程逐步講解

    Vue數(shù)據(jù)代理的實(shí)現(xiàn)流程逐步講解

    通過一個(gè)對(duì)象代理對(duì)另一個(gè)對(duì)象中的屬性的操作(讀/寫),就是數(shù)據(jù)代理。要搞懂Vue數(shù)據(jù)代理這個(gè)概念,那我們就要從Object.defineProperty()入手,Object.defineProperty()是Vue中比較底層的一個(gè)方法,在數(shù)據(jù)劫持,數(shù)據(jù)代理以及計(jì)算屬性等地方都或多或少的用到了本函數(shù)
    2023-01-01
  • elementui中使用el-tree控件懶加載和局部刷新

    elementui中使用el-tree控件懶加載和局部刷新

    這篇文章主要介紹了elementui中使用el-tree控件懶加載和局部刷新,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 詳解Vue.js使用Swiper.js在iOS<11時(shí)出現(xiàn)錯(cuò)誤

    詳解Vue.js使用Swiper.js在iOS<11時(shí)出現(xiàn)錯(cuò)誤

    這篇文章主要介紹了詳解Vue.js使用Swiper.js在iOS<11時(shí)出現(xiàn)錯(cuò)誤,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09
  • vue項(xiàng)目main.js使用方法詳細(xì)介紹

    vue項(xiàng)目main.js使用方法詳細(xì)介紹

    這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目main.js使用方法的相關(guān)資料,main.js文件是程序的入口文件,加載各種公共組件,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-09-09
  • Vue組件間通信方法總結(jié)(父子組件、兄弟組件及祖先后代組件間)

    Vue組件間通信方法總結(jié)(父子組件、兄弟組件及祖先后代組件間)

    這篇文章主要給大家介紹了關(guān)于Vue組件間通信的相關(guān)資料,其中包括父子組件、兄弟組件及祖先后代組件間的通信,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • vue路由對(duì)不同界面進(jìn)行傳參及跳轉(zhuǎn)的總結(jié)

    vue路由對(duì)不同界面進(jìn)行傳參及跳轉(zhuǎn)的總結(jié)

    這篇文章主要介紹了vue路由對(duì)不同界面進(jìn)行傳參及跳轉(zhuǎn)的總結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • vue前端常用的工具類總結(jié)

    vue前端常用的工具類總結(jié)

    這篇文章主要為大家詳細(xì)介紹了6個(gè)vue前端常用的工具類,可直接復(fù)用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • 基于vue的換膚功能的示例代碼

    基于vue的換膚功能的示例代碼

    本篇文章主要介紹了基于vue的換膚功能的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • Element-ui的table中使用fixed后出現(xiàn)行混亂情況的解決

    Element-ui的table中使用fixed后出現(xiàn)行混亂情況的解決

    這篇文章主要介紹了Element-ui的table中使用fixed后出現(xiàn)行混亂情況的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10

最新評(píng)論