前言:不當心發現線上一個bug,看了下代碼,瞭解到由於用Vue.nextTick的場景不對,在此作個記錄。html
具體場景是,修改文件夾名稱時,彈出一個修更名稱的彈出框vue
此時文件名「啦啦啦」會帶到編輯文件夾的彈出框中。修改保存後,文件名變成「啦啦啦123」,而後再次修改文件夾名,結果:異步
此時爲何文件名沒有帶過去?this
經過查看代碼瞭解到 編輯文件夾 彈出框是一個子組件,父組件觸發修改文件名的事件時,經過 folderToBeRenamed 傳遞新的數據spa
this.$nextTick(() => { this.folderToBeRenamed = newFolderName })
子組件再經過props 獲取 folderToBeRenamed調試
並用 watch 監聽code
watch: { folderToBeRenamed () { this.folderName = this.folderToBeRenamed.folder_name } }
folderName就是子組件要獲取的數據,看起來好像有道理,但是爲何只起到一次監聽做用?經過調試發現,只有第一次點擊修改文件名,watch裏的事件會執行;後續無論folderToBeRenamed是否改變都不會執行watch裏的事件了。htm
先看下官網的解釋事件
有點難懂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 此次變化。
這裏的邏輯原本是比較簡單的,父組件傳值,子組件直接獲取就能夠了。爲何須要父組件用Vue.nextTick(),子組件用watch監聽,我也不太清楚。由於本身對Vue.nextTick()用法也不太熟,因此在此記錄,謹防踩坑_(:з」∠)_