為什麼直接修改陣列長度或設定陣列項的索引時,Vue不能檢測到陣列的變動?

時間 2021-05-31 00:20:12

1樓:陳小成

vue中的陣列的監聽不是通過Object.defineProperty來實現的,是通過對'push', 'pop','shift','unshift','splice', 'sort','reverse'這幾個改變陣列本身的方法執行後來通知監聽達到的,原始碼傳送門:https:

2樓:井底之蛙

其實說白了就是vue的監聽機制都是通過defineproperty來實現的,但是不能檢測物件新新增的屬性,物件可以初始化的時候就設定好屬性,不加新屬性,陣列也是物件,然而如果要求陣列初始化的時候就設定好所有屬性(索引),不能新增索性(改變長度),顯然是不可能的,那麼要陣列也就沒用了。

3樓:Roc.L

vue用defineproperty下的setter和getter方法做依賴跟蹤的。

MDN:

陣列的 length 屬性重定義是可能的,但是會受到一般的重定義限制。(length 屬性初始為 non-configurable,non-enumerable 以及 writable。對於乙個內容不變的陣列,改變其 length 屬性的值或者使它變為 non-writable 是可能的。

但是改變其可列舉性和可配置性或者當它是 non-writable 時嘗試改變它的值或是可寫性,這兩者都是不允許的。)然而,並不是所有的瀏覽器都允許 Array.length 的重定義。

簡單來說length的命名訪問器屬性set和get你不能動它,也就無法設定setter和getter

至於陣列下的索引是可以用setter和getter的但是為啥vue下索引也不允許更新呢?

因為length = 5的陣列,未必索引就有4,這個索引(屬性)不存在,就沒法setter了。

4樓:賀師俊

因為沒有辦法監聽任意屬性。

當然現在Proxy是可以做到這點的,不過乙個是相容性問題,另乙個是如果用了Proxy就是乙個新物件,跟現在Vue在原本物件上設定 getter/setter 的方式不同。

v for 修改迴圈列表陣列時, 為什麼不能只對陣列中某一項上直接修改,相應的dom會更新?

Ant周 貘吃饃香 Jason Chen alvinyuxt 感謝幾位,看到貘大和各位的回答,原理也明白了,Jason chen已經講的很明白了,而且是 每個陣列的 prototype 單獨 hack push 這些操作 這個也是我之前不知道的,非常感謝。接下來我會打算開始對Vue原始碼開始慢慢研讀...

這裡沒有定義陣列指標,為什麼會出現陣列,只是僅僅定義乙個指標而已,為什麼可以當陣列用?

作為業餘愛好者,我來解釋一下。int a 3 4 表明,a是乙個二維陣列的首位址,並且,a 包含了3個int 型陣列,a 0 a 1 a 2 每個陣列的長度為4。後面的 a 0 0 是第1個元素的位址,也就是陣列 a 0 的首位址,這個陣列長度為4。因此,p 相當於乙個,長度為4 的int 型陣列。...

c 陣列定義為什麼會這樣?

wzf2000 初始化問題不說了,前面的答主說的夠了。至於為什麼會TLE,可以想想輸入的不足四位數會怎樣。結合前面答主所說就可明白。至於那位說會CE的答主,可能不知道在MinGW或類似編譯環境下std string確實是可以直接呼叫的,一般OJ也不太可能使用MSVC做編譯環境。換句話說,不同編譯環境...