響應(yīng)式與數(shù)據(jù)更新
在vue中咐刨,需要展示在頁面上的數(shù)據(jù)必須在data中聲明昙衅,沒有在data中聲明的屬性將不會(huì)被vue感應(yīng)。
vue會(huì)使用Object.defineProperty 方法 將data中的屬性變成getter/setter型屬性定鸟,每一個(gè)vue組件會(huì)對(duì)應(yīng)一個(gè)watcher而涉,它會(huì)在組件渲染的過程中把“接觸”過的數(shù)據(jù)屬性記錄為依賴。之后當(dāng)依賴項(xiàng)的 setter 觸發(fā)時(shí)联予,會(huì)通知 watcher啼县,從而使它關(guān)聯(lián)的組件重新渲染。
雖然在初始化之后沸久,不能去聲明data中的屬性(對(duì)于已經(jīng)創(chuàng)建的實(shí)例季眷,Vue 不允許動(dòng)態(tài)添加根級(jí)別的響應(yīng)式屬),
但可以對(duì)嵌套對(duì)象中添加屬性卷胯,在開發(fā)過程中子刮,往往會(huì)遇到一個(gè)問題,即某個(gè)嵌套對(duì)象中增加或刪除了某個(gè)屬性窑睁,但頁面表現(xiàn)上挺峡,對(duì)應(yīng)元素沒有生成或被刪除葵孤。出現(xiàn)這個(gè)問題的原因在于vue無法檢測(cè)到對(duì)象屬性的添加和刪除,如果要添加或刪除屬性沙郭,要生成新對(duì)象佛呻,替換這個(gè)老對(duì)象 ,示例:
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
vue對(duì)dom的更新是一個(gè)異步行為病线,如上述代碼吓著,并不是執(zhí)行了這一句,someObject對(duì)應(yīng)的dom中的值就會(huì)立即改變送挑,如果在這句后面直接抓取dom取值绑莺,那么取得的還是舊值。 在實(shí)際開發(fā)中惕耕,如果混合使用了data數(shù)據(jù)更新纺裁,與dom抓取取值,很可能出現(xiàn)值不是最新的情況司澎。
這個(gè)問題的根本原因就是vue對(duì)dom的更新是一個(gè)異步行為欺缘,dom并沒有馬上更新,實(shí)際上挤安,vue在對(duì)數(shù)據(jù)更新時(shí)谚殊,會(huì)創(chuàng)建一個(gè)異步隊(duì)列,一次性更新同一個(gè)事件循環(huán)中設(shè)置的所有數(shù)據(jù)蛤铜,組件會(huì)在下一個(gè)事件循環(huán)更新(即異步隊(duì)列中的數(shù)據(jù)會(huì)在下一個(gè)事件循環(huán)中更新)嫩絮。vue提供了nextTick(),該方法接收一個(gè)回調(diào)函數(shù)围肥,回調(diào)函數(shù)將在 DOM 更新完成后被調(diào)用剿干,即可保證回調(diào)中抓取的dom值為最新值。