天天看點

vue下$nextTick及原理淺析

vue下$nextTick及原理淺析
Merlo
Merlo
5 人贊同了該文章
vue->$nextTick
引用官方的話:為了在資料變化之後等待 Vue 完成更新 DOM ,可以在資料變化之後立即使用 Vue.nextTick(callback)

ex1
<div>
    <button @click="add">add</button>
    <div ref="tagName">{{name}}</div>
</div>
data () {
  return {
    name: merlo
  }
}
methods: {
  add() {
    this.name = 'iron man'
    console.log(this.$ref['tagName'].innerHTML) // 仍然是merlo
    this.$nextTick((v) => {
      console.log(this.$ref['tagName'].innerHTML) // 已經變成iron man
    })
  }
}
ex2
<div>
    <button @click="add">add</button>
    <div ref="tagName" :style="css">{{info}}</div>
</div>
data() {
  return {
    css: { height: '666px'}
  }
}
methods: {
  add() {
    this.css = { height: '666666px' }
    console.log(this.$ref['tagName'].offsetHeight) // 依然666px
    this.$nextTick((v) => {
      console.log(this.$ref['tagName'].offsetHeight) // 變成666666px
    })
  }
}
相關原理

在 Vue 2.4 之前都是使用的 microtasks,但是 microtasks 的優先級過高,在某 些情況下可能會出現比事件冒泡更快的情況,但如果都使用 macrotasks 又可能會出現 渲染的性能問題。是以在新版本中,會預設使用 microtasks,但在特殊情況下會使用 macrotasks,比如 v-on。
macrotasks: microtasks的作用是用來排程應在目前執行的腳本執行結束後立即執行的任務。 例如響應事件、或者異步操作,以避免付出額外的一個task的費用。

I/O
setTimeout
setInterval
setImmediate
requestAnimationFrame
UI rendering
microtasks: 就是常說的任務隊列task queue,作用是為了讓浏覽器能夠從内部擷取javascript / dom的内容并確定執行棧能夠順序進行。

process.nextTick
Promises
Object.observe
MutationObserver
ex:

setTimeout(function(){
        console.log(1)
    },0);
    new Promise(function(resolve){
        console.log(2)
        for( var i=100000 ; i>0 ; i-- ){
            i==1 && resolve()
        }
        console.log(3)
    }).then(function(){
        console.log(4)
    });
    console.log(5);
    // 以上列印結果 2,3,5,4,1
tip:

在Microsoft Edge, Firefox 40, iOS Safari 以及 desktop Safari 8.0.8 中setTimeout會先于Promise