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

時間 2021-06-03 13:55:25

1樓:Ant周

@貘吃饃香

@Jason Chen

@alvinyuxt 感謝幾位, 看到貘大和各位的回答,原理也明白了, Jason chen已經講的很明白了,而且是「 每個陣列的 prototype 單獨 hack push 這些操作 」這個也是我之前不知道的,非常感謝。 接下來我會打算開始對Vue原始碼開始慢慢研讀下,這個問題會繼續關注,後面會具體分析下Vue對Array是怎麼hack操作的。

2樓:Jason Chen

回答這個問題就要提到 Vue.js 的檢視響應資料變化的原理。

對於 object 型別的 data,直接用 Object.defineProperty 定義 getter 和 setter。在 setter 的階段對提交檢視的更新(簡單來說)

而對於 Array 就不是這麼簡單了,陣列的每個元素是沒有 getter 和 setter,所以不能簡單的 defineProperty。而只能監聽一些操作,例如 push, pop 等。而這些在 Array.

prototype 上的,所以 Vue.js 是先儲存下來 Array.prototype,對每個陣列的 prototype 單獨 hack push 這些操作,然後修改原型。

(不改 Array.prototype 是因為這是全域性共享的,總不能在 Vue.js 外面修改了陣列 Vue.

js 的檢視卻更新了吧?)

說回你的 Demo,Vue.js 對你陣列裡的物件進行了 Object.defineProperty 操作,如果你把陣列裡面的物件改成其他原始型別(String, Number 等)就不行了。

我改了一下你的 Demo,這樣就不行了:Edit fiddle - JSFiddle

3樓:alvinyuxt

你的demo能被監聽到是因為,Vue對陣列內的value都做一遍defineReactive的操作,所以你的demo裡面改變觸發的是物件的setter。

4樓:貘吃饃香

瀉藥簡單的說就是 Object.defineProperty(ies) 的 get set 監聽不到這種變化,無法通知 View 更新。

所以,它的解決方法是,新增 Array 一系列同名方法在陣列物件的原型鏈上,所用的陣列處理方法都是包裝原始方法並加料的(通知 View 更新等)

但是你的 demo 好像不是這意思,它最終定位到陣列具體 idx 的 Object 上,改變的 Object 某 key 的 value,這個是可以被 set 到的。

如何評價孜循留學機構?

名校之星 對這個機構不是很了解。但是中介應該都是差不多的,運營模式大同小異。一直強調的一點就是中介機構的存在不是為了做慈善,他們是為了盈利賺錢,中介顧問也只是在做乙份工作,需要賺錢。明白這一點後,就會知道中介不是萬能的,也不可能真的很實在的全心全意為你著想,他們只是在保證自己利益的基礎上給你做推薦和...

如何解釋經絡的循行規律?

黃帝曾經問過岐伯這個問題,岐伯給他的回答是 這個不只是用語言表達的,更是切尋按壓時手下有感的,只要能摸出它運動的方向,就可以知道它循行的方向了 問曰 何以明之?對曰 以言道之,切而驗之,其非必動,然後可以明逆順之行也。什麼意思呢?舉個簡單的例子,我們把脈的時候摸的是橈動脈,也就是手太陰肺經的循行所過...

關於六經中循經傳的問題?

明郎中 一 不看 傷寒論 原版怕你看不懂?遲早還是要看看。二 胡希恕先生的版本是個人注本,目前爭議很大。三 六經的生化原理和六氣的相互關係,截止到目前,各家眾說紛紜,沒有定論,在我看來沒有一家完全揭開。五 太陽 陽明 少陽 太陰 少陰 厥陰是原版 傷寒論 的順序。六 太陽 少陽 陽明 太陰 厥陰 少...