當前位置:成語大全網 - 新華字典 - 壹張圖說清楚Vue3父子組件傳值,以及props可否改的本質問題

壹張圖說清楚Vue3父子組件傳值,以及props可否改的本質問題

為了避免混淆,先介紹壹下後端語言用的類。

壹般類可以包含內部成員、屬性、方法、事件等。

內部成員壹般都是私有的(其實也可以設置為公有),調用者不可以直接訪問內部成員,而是要通過屬性來訪問內部成員。

屬性是內部成員的安全通道,可以限制訪問方式,比如只讀;也可以設置關卡,比如年齡 > 18 且 年齡 < 60的才可以通過。

vue 的組件,也可以設置 data、props、computed、methods等,看起來和類的設置很像,但是卻有著本質的區別。

所以請不要把類的理解和使用方式,生硬的套在 vue 的父子組件上面,要註意區分。

現在來討論壹下,props 到底可不可以改的問題。

按照官網的說法,子組件是不可以修改 props 的,原因雲雲,於是好多人也跟著說不能改,改了就雲雲。

那麽本質原因是啥呢?知其然還要知其所以然!

這個要從js的數據類型說起,js的類型比較亂,有很多種劃分方式,從傳遞的角度來看,可以分為傳值類型和引用類型。

對於傳值類型,傳遞副本之後,副本和“本尊”已經沒有任何聯系了,副本隨便改,都不會影響“本尊”。

引用類型,傳遞的是自己的地址(指針),所以可以通過地址修改“本尊”的屬性,這樣改副本就可以影響到“本尊”。

vue組件的 props 能改與不能改,就是這兩種傳遞方式導致的。

我們經常用到組件的 props,那麽 props 到底是什麽樣子的呢?

這裏以 Vue3 為例來分析壹下,我們設置壹個簡單的父子組件,設置幾種常見的類型:

子組件定義壹個 props,有基礎類型,和引用類型幾個成員。基礎類型需要使用 emit 來修改,引用類型(reactive),可以直接通過 proxy 的攔截原理來方向修改。

模板:

js:

父組件定義幾個類型的data傳遞給子組件。基礎類型用 ref,引用類型使用 reactive。因為這樣可以有響應性。

我們先來看看 props 的打印結果,發現是壹個套娃 proxy:

在 vue3 裏面,reactive、shallowReactive、readonly、shallowReadonly 都用了proxy,那麽到底是哪壹種呢?

簡單測試壹下就會發現是 shallowReadonly(淺層只讀),那麽問題來了,既然不讓改,為啥不用 readonly?是遺漏了嗎?

我猜測這是壹個平衡各種需求後的折中處理方案。

然後可能官方為了避免心智負擔,於是幹脆壹刀切,就說不讓改props,這樣就省事了。

而對於懂得原理的,那就可以傳遞引用類型,實現更簡潔的操作方式。

上圖比較清晰的表達了數據的流向。

壹個常見的例子就是,“彈窗顯示表單”。以element-plus 為例:

父組件:

子組件

模板

這樣父組件和子組件都可以輕松的控制 el-dialog 了。