Closed Frenkieli closed 4 years ago
問題一、觸發順序問題
這邊去測試了 nextTick 、 computed 的set 和 beforeUpdate 的觸發順序
預想中 computed的set應該會先觸發更改資料,而後觸發刷新DOM前的beforeUpdate,最後在觸發DOM刷新結束的 nextTick
但實際測試確是 nextTick => computed : set => beforeUpdate ,nextTick沒有像文件所講的在DOM更新結束updated後才觸發
測試結果沒有在DOM觸發結束後才拿到 e.target.value 請問是 nextTick 的使用方式在哪邊出錯了嗎?
測試過程殘骸在檔案 vue-bike\src\components\searchBar.vue 下面
Hi, 這個問題很有趣。
按照你的設定,我猜測你預想 nextTick
應該會在最後才執行對吧? 但結果卻在一開始就出現了。
這裏我講一下我的看法。
你在 input
裡面同時用 v-model
綁定 conditionName
,並且加入了 keydown
事件來執行 searchStart
method:
<input
ref="searchName"
id="searchName"
class="form-control"
type="text"
v-model="conditionName"
@keydown="searchStart"
>
這是 computed:
conditionName: {
get: function({conditionNameProp}){
return conditionNameProp;
},
set: function(val){
let vm = this;
vm.$emit('update:conditionNameProp', val);
vm.$emit('page-change-event', 0);
console.log(Date.now(), '設定');
}
}
這是 method:
searchStart(){
let vm = this;
console.log('searchStart 觸發');
vm.$nextTick(function(){
console.log(Date.now(), 'searchStart nextTick 刷新', vm.$refs.searchName.value);
})
}
結果當 input 被修改時, keydown
事件的 searchStart
先被執行,
並且印出 "searchStart 觸發"、連同 nextTick
的刷新也印出。
然後才進到 computed
的設定,最後才到 beforeUpdate
hook 的 callback function。
這是因為 $nextTick
被調用的時候,會先去檢查「 DOM 操作相關的 queue」 是否還有未完成的任務,
如果有,則去等待 DOM 更新完成後執行,如果沒有就馬上執行。
跟 setTimeout
0 秒的情況不同的是,setTimeout
會等待所有非主線程的任務完成後才執行。
而真正寫入 data / DOM 其實是在 computed 的 set 而不是 methods。
最好的檢驗方式,就是我們將 computed
與 methods
分別加入 setTimeout
0 秒 與 nextTick
的操作:
// computed
conditionName: {
get: function({conditionNameProp}){
return conditionNameProp;
},
set: function(val){
let vm = this;
vm.$emit('update:conditionNameProp', val);
vm.$emit('page-change-event', 0);
console.log(Date.now(), '設定');
// setTimeout 0 秒
window.setTimeout(() => { console.log(Date.now(), 'computed - setTimeout'); }, 0);
// nextTick
vm.$nextTick(function(){
console.log(Date.now(), 'computed-set nextTick 刷新', vm.$refs.searchName.value);
});
}
// methods
searchStart () {
let vm = this;
console.log('searchStart 觸發');
// setTimeout 0 秒
window.setTimeout(() => { console.log(Date.now(), 'searchStart - setTimeout'); }, 0);
// nextTick
vm.$nextTick(function(){
console.log(Date.now(), 'searchStart nextTick 刷新', vm.$refs.searchName.value);
});
}
},
在 input 被更新之後,會依序出現這樣的結果:
在 method 裡的 nextTick 會先被執行,然後進到 computed 、 beforeUpdate , 等待 DOM 同步完成後執行 computed 的 nextTick,最後才是兩者的 setTimeout。
希望有幫助到你對 nextTick 順序的觀念理解 :)
問題一、觸發順序問題
這邊去測試了 nextTick 、 computed 的set 和 beforeUpdate 的觸發順序
預想中 computed的set應該會先觸發更改資料,而後觸發刷新DOM前的beforeUpdate,最後在觸發DOM刷新結束的 nextTick
但實際測試確是 nextTick => computed : set => beforeUpdate ,nextTick沒有像文件所講的在DOM更新結束updated後才觸發
測試結果沒有在DOM觸發結束後才拿到 e.target.value 請問是 nextTick 的使用方式在哪邊出錯了嗎?
測試過程殘骸在檔案 vue-bike\src\components\searchBar.vue 下面