1 回答

TA貢獻1876條經(jīng)驗 獲得超5個贊
是這樣的,你console.log一下跟vue綁在一起的data里面屬性,你會發(fā)現(xiàn)那些打印出來多了兩個東西:
setter
getter
沒錯,vue檢測數(shù)組變動靠的就是這兩個屬性
而這兩個屬性,根據(jù)vue文檔的說法,它是使用了js原生的Object.defineProperty()
(其實準(zhǔn)確來講應(yīng)該是es的東西)
簡單地講,就是js屬性的屬性。。。怎么那么別扭。。。就是描述Array或者Json等Object類型里面的值的屬性,比如一個arr=[1,2,3,4]
,屬性的屬性就是里面的1具有的屬性。。。而且還有兩個:數(shù)據(jù)屬性和訪問器屬性。
比如數(shù)據(jù)屬性中的 Enumberable,如果它為false,那么即使它描述的那個屬性存在于json里面,也不會被for-in遍歷到。
好,回到正題,也就是vue對數(shù)組的檢測方法
它使用是Object類型底層的訪問器屬性來檢測數(shù)組變動的。
訪問器屬性存在兩個方法(姑且叫做方法吧,原文是叫attribute,但翻譯成屬性的話感覺太亂了。。而它們的作用又如同面向?qū)ο罄锩娴姆椒ㄒ粯樱?/p>
Get :在讀取時調(diào)用的函數(shù)。默認值為undefined
Set :在寫入時調(diào)用的函數(shù),默認值為undefined
Vue的數(shù)組檢測變動就基于上面這兩個方法。
然而,都說了是es底層定義的東西,js是不可能直接就修改訪問上面的Get和Set,必須通過Object.defineProperty這個方法進行修改:
var json={ a:1 }; /*當(dāng)json.a變動時打印修改信息*/ Object.defineProperty(json,'a',{ set:function(newValue){ console.log(this.value+'->'+newValue) }, get:function(){ console.log(this.value) } })
據(jù)說,第一個實現(xiàn)Object.defineProperty方法的瀏覽器是IE8,想不到吧,渣渣IE居然是第一個實現(xiàn)的。。。這也是為什么vuejs不支持ie8以下的垃圾ie了的原因了。
而且,vue為了檢測push這些操作造成的數(shù)組變動,都是將這些Api重新封裝了一遍的。。。
所以當(dāng)你直接 vm.items[0]={}
這樣的時候,vue根本沒法給你做一個Object.defineProperty處理,自然也搞不出setter和getter,自然無法檢測數(shù)組變動。。。
添加回答
舉報