firehtml
讀在最前面:node
一、此文章銜接Vue 虛擬Dom 及 部分生命週期初探,相關總體知識點請先閱讀後再繼續本文閱讀ui
問:子組件中明明有watch value,爲何this.$emit('input', 888);沒有觸發watch回調,反而在父組件data數據變化後觸發回調?this
<child v-model="b"></child> var child = Vue.extend({ template: '<p>數據響應及render相關-案例說明</p>', props: { value: { required: true } }, mounted() { this.$emit('input', 888); }, watch: { value(val, oldVal) { console.log(val, oldVal, 'child') } } });
點擊查看涉案代碼htm
以下圖:blog
關鍵執行順序分析:生命週期
一、子組件this.$emit('input', 888)執行內存
二、父組件執行這段代碼,settime 去更新父組件值get
created() { this.b = 1 setTimeout(() => { this.a = 3 }, 1000) }
三、settime執行後,觸發父組件a的set -> 觸發watch -> 觸發vm.render -> 觸發patch-> 觸發 validPros -> 觸發子組件pros更新 -> 觸發value更新 ->回調watchinput
大體流程以下圖
el-select 中也是實現了watch value(詳見源碼),因此在父級中引用組件時v-model值沒有在data中申明的狀況下,可能出現切換選擇項沒有反應,當其餘data值變化時,致使render渲染,select就會自動選中的異常
備註:
一、observe不會對不在data中的數據進行處理
二、頁面更新時,會執行render,全部的數據綁定會在內存中再次執行,包括{{xxx}} , {{methods}}, {{computed}} 等,生成新的vnode
三、一個時間週期中的數據更新,非當即執行的watcher,都會統一進入queueWatcher,在下個tick進行執行
by:海豚灣-豐