官方解釋:vue
當你把一個普通的 JavaScript 對象傳給 Vue 實例的 data 選項,Vue 將遍歷此對象全部的屬性,並使用 Object.defineProperty 把這些屬性所有轉爲 getter/setter。
不是在data上添加的屬性,由於在實例化是沒有使用Object.definePrototype設置屬性的getter/setter,watcher沒有建立這些屬性的依賴,因此當數據變化時,沒法獲取到數據更改的通知,也就不能觸發視圖re-render。api
查看vue的源代碼,加載源代碼後,會首先調用initMixin構建Vue。只有當使用new實例化Vue時纔會調用_init,而且這時options裏的data還只是原生對象函數
接着調用initState,用來初始化一些須要響應式式處理的數據,方法。包含props,data,computed,watch,methods(將方法的對象設置爲當前vue實例,而且判斷方法名是否和props有重複的)。code
若是options參數裏沒有data,就默認給一個空的,而後直接調用observe對data裏的屬性建立觀察者實例server
調用initData,作數據檢查,是不是原生對象,檢查data對象裏的屬性是否和props對象的屬性有重合的。而後調用observe(),對data對象裏的每一個屬性建立一個觀察者對象。對象
調用Observer回調函數(保證每一個Vue實例/組件的data都是獨立的,不會形成做用域污染),定義觀察者類,一旦被觀察者對象應用了Observer類,就會將對象的每一個屬性設置成getter/setter,從而收集依賴和觸發更新blog
調用def方法,這個方法的做用就是最後執行Object.definePrototype,將每一個data裏的屬性設置爲getter/setter。ip
至此,全部具備響應式的屬性都在initState被初始化了和監聽了。作用域
若是想要動態添加數據到data對象上,就須要用到Vue.set方法,首先會判斷是不是數據,而後若是對象上存在屬性(key)就直接設置target[key] = val;接着檢查是不是Vue實例,是否應被設置爲觀察者對象;只有已經被設置爲觀察者對象的對象,才能調用Vue.set動態添加屬性和值;這也就是管網API上說的get
注意對象不能是 Vue 實例,或者 Vue 實例的根數據對象。