2017-09-19 27 views
3

我在寫一個遞歸樹渲染器,並且忍受這個「避免直接改變道具」的警告。避免直接改變道具......但這似乎是官方的例子呢?

據我所知,「支撐事件」意味着孩子不能/不應該直接改變父母的數據。我可以通過編寫大量的代碼來避免這個錯誤,其中一個組件$emit改變了,它的父節點捕獲它並且重新發射它,並且一直到頂層組件,最終可以改變數據,然後渲染通過那個樹。雖然我得到了一個泛型組件需要不知道其父類的用例,但對於遞歸組件,它看起來非常低效。

我注意到提供了官方VueJs 2 tree view example。但是查看該代碼顯示子組件傳遞屬於父項的對象,但子組件被允許直接更新(例如,在addChild或changeType方法中)。

我作了一個variation of that jsfiddle作爲證明。我所有的變化都是將父母的數據輸出爲json,以便您可以看到它已更改。一開始它看起來像這樣:

{"name":"My Tree","children":[{"name":"hello"},{"name":"wat"} 

然後,如果你點擊進入了第一個父,然後雙擊1. hello觸發changeType你會發現現在家長的數據發生變化:

{"name":"My Tree","children":[{"name":"hello","children":[{"name":"new stuff"}]},{"name":"wat"}... 

...但可怕的「避免直接改變道具」警告並未被解僱。

所以我明顯缺少一些細微差別。這很令人沮喪,因爲有很多這方面的問題,我害怕增加一個副本。但我覺得這是不同的,因爲我問:「爲什麼的例子不是直接改變一個道具?」!

回答

4

對象和陣列由參考它是完全可以接受的突變的屬性的對象的或者被因爲未改變參考 pased道具數組的內容通過。對象屬性的更改將反映在使用特定引用的任何地方。這在official documentation中得到解決。

注意,對象和在JavaScript數組通過引用傳遞,所以 如果丙是一個數組或對象,突變子內的物體或陣列本身 會影響父狀態。

是你嘗試傳過來的屬性的對象設定爲一個完全不同的對象,警告將在控制檯中顯示。

您是否選擇利用這是設計考慮因素。在Vue樹的例子中,代碼改變了對象的屬性,並且這些改變被反射到任何地方。一個反例可能是編輯用戶。如果您有一個用戶組件,並且希望對該對象所做的更改設置爲,則只有在更改被認爲有效(允許取消更改)時纔會反映以外的組件,您可以創建對象的內部副本,編輯副本,並在認爲可以接受時發佈變更。

+0

好的,我非常感謝。我想我明白了。在我的情況下,我將一個數組設置爲一個新數組,但我應該通過'Array.splice()'來完成,所以引用依然存在。會試試看! – artfulrobot

相關問題