Vue this.$nextTick原理


  雖然 Vue.js 通常鼓勵開發人員沿着“數據驅動”的方式思考,避免直接接觸 DOM,但是有時我們確實要這么做。比如一個新聞滾動的列表項。如果在這里需要操作dom, 應該是等待 Vue 完成更新 DOM之后。

一、新聞滾動列表

1、在created函數中獲取后台數據;

2、模板引擎中用v-for生成列表項;

3、調用滾動函數,假設該滾動函數式原生方法寫的;

4、什么時候開始調用滾動函數比較合適呢?

 

二、this.$nextTick()

官方解釋:將回調延遲到下次 DOM 更新循環之后執行。在修改數據之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一樣,不同的是回調的 this 自動綁定到調用它的實例上。

Vue.component('example', {
  template: '<span>{{ message }}</span>',
  data: function () {
    return {
      message: 'not updated'
    }
  },
  methods: {
    updateMessage: function () {
      this.message = 'updated'
      console.log(this.$el.textContent) // => 'not updated'
      this.$nextTick(function () {
        console.log(this.$el.textContent) // => 'updated'
      })
    }
  }
})

 

三、新聞滾動列表中的this.$nextTick()放哪里?

  因為數據是根據請求之后獲取的,所以應該放到請求的回調函數里面。

 

四、原理【重點】

前面只是利用一個例子引入話題。

在進行獲取數據后,需要對新視圖進行下一步操作或者其他操作時,為什么獲取不到 DOM呢?

原因:

這里就涉及到 Vue 一個很重要的概念:異步更新隊列(JS運行機制 、 事件循環)。

Vue 在觀察到數據變化時並不是直接更新 DOM,而是開啟一個隊列,並緩沖同一事件循環中發生的所有數據改變。

在緩沖時會去除重復數據,從而避免不必要的計算和DOM操作。

然后,在下一個事件循環 tick 中,Vue 刷新隊列並執行實際(已去重的)工作。

所以如果用 for 循環來動態改變數據100次,其實它只會應用最后一次改變,如果沒有這種機制,DOM就要重繪100次,是一個很大的開銷,損耗性能。

例子:

//改變數據
vm.message = 'changed'

//想要立即使用更新后的DOM。這樣不行,因為設置message后DOM還沒有更新
console.log(vm.$el.textContent) // 並不會得到'changed'

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

  

五、常見應用

點擊按鈕顯示原本以 v-show = false 隱藏起來的輸入框,並獲取焦點。

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

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

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM