關於Vue.nextTick()的使用

前言:不當心發現線上一個bug,看了下代碼,瞭解到由於用Vue.nextTick的場景不對,在此作個記錄。html

1、bug重現

具體場景是,修改文件夾名稱時,彈出一個修更名稱的彈出框vue

clipboard.png

此時文件名「啦啦啦」會帶到編輯文件夾的彈出框中。修改保存後,文件名變成「啦啦啦123」,而後再次修改文件夾名,結果:異步

clipboard.png

此時爲何文件名沒有帶過去?this

2、代碼邏輯

經過查看代碼瞭解到 編輯文件夾 彈出框是一個子組件,父組件觸發修改文件名的事件時,經過 folderToBeRenamed 傳遞新的數據spa

this.$nextTick(() => {
   this.folderToBeRenamed = newFolderName
})

子組件再經過props 獲取 folderToBeRenamed調試

並用 watch 監聽code

watch: {
    folderToBeRenamed () {
      this.folderName = this.folderToBeRenamed.folder_name
    }
 }

folderName就是子組件要獲取的數據,看起來好像有道理,但是爲何只起到一次監聽做用?經過調試發現,只有第一次點擊修改文件名,watch裏的事件會執行;後續無論folderToBeRenamed是否改變都不會執行watch裏的事件了。htm

3、瞭解Vue.nextTick()

先看下官網的解釋事件

clipboard.png

有點難懂o(╯□╰)oip

看到知乎上的解釋:

HTML: <div id="testCount" v-html="message"></div>

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

//想要當即使用更新後的DOM。這樣不行,由於設置message後DOM尚未更新
console.log(document.getElementById('testCount').innerHTML) // 並不會獲得'changed'

//這樣能夠,nextTick裏面的代碼會在DOM更新後執行
Vue.nextTick(function(){
    console.log(document.getElementById('testCount').innerHTML) //能夠獲得'changed'
})

因此 vue的nextTick的做用相似setTimeout,再添加一個新的空的異步事件,執行完異步事件後調用callback。

因此回到咱們前面的bug,能夠明白,子組件只感覺到folderToBeRenamed的一次變化,就至關於for循環裏的setTimeout

for(var i = 0; i < 3; i++) {
   setTimeout(function() {
       console.log('timeout' + i);
   })
}

最後輸出的i都是3,也就是隻能感覺到i從0變爲3 此次變化。

4、修改bug

這裏的邏輯原本是比較簡單的,父組件傳值,子組件直接獲取就能夠了。爲何須要父組件用Vue.nextTick(),子組件用watch監聽,我也不太清楚。由於本身對Vue.nextTick()用法也不太熟,因此在此記錄,謹防踩坑_(:з」∠)_

相關文章
相關標籤/搜索