在談 props
之前,先來說說子元件的資料來源:
- 自己的資料:也就是子元件裡面自定義的資料。
- 父元件
props
進子元件的資料:這是子元件跟父元件借資料來用,不屬於子元件所有。
- Store 裡面大家公用的資料: 例如放在 pinia 與 vuex 裡面的資料。
如果是要同層級的元件間互相傳遞資料,或是跨好幾個層級的元件要傳遞資料,並不適合使用 props。
props 是子元件的資料接收器
父元件如果要傳送資料給子元件必須透過 props
,而且必須遵守單向資料流的規則 ,也就是子元件接收到父元件的資料後,不能去修改那個資料,因為那份資料可能是給很多個子元件共用的。
內層子元件定義 props 接收
以 <script setup>
來舉例,必須在子元件先定義 defineProps
。
或是用一個變數來定義 defineProps
。
可以在陣列中放入多個接收父元件資料的 props
聲明,Vue 才能知道父元件傳入子元件的哪些是 props。而defineProps
預設會返回一個帶有所 props
屬性的物件。
一個元件可以有多個 props,預設都可以接收任何型別的值,包含字串、數值、布林值、陣列、物件及函數。
子元件內的 props 命名要使用小駝峰形式。
父元件中用 v-bind 綁定props,則使用 kebab-case
props 接收動態資料
而在父層中要傳送資料給子元件,可以這樣做:
在上面的範例中,使用 v-bind
綁定內層子元件的 props
,後面則是放外層父元件要傳送的資料,口訣為「前內後外」。
假設子元件的內層 defineProps 如此聲明:
父元件的資料如此定義:
外層父元件可以如此傳資料給子元件:
props 接收靜態資料
如果是靜態資料,依樣是遵守「前內後外」的原則,但是不用 v-bind
綁定。
外層父元件可以如此傳資料給子元件:
示範範例
props 與 v-for 的結合
如果父元件要傳給子元件的資料是陣列的形式,而且每個子元件要呈現的資料隨陣列的 index 不同,可以搭配 v-for
來傳遞多筆資料。
父元件中的資料型態:
在子元件中定義 defineProps
:
在父元件中使用 v-for
渲染多個子元件
換言之,假設要在父元件中放入多個子元件,而且子元件分別要呈現不同資料,則資料可以設計成陣列物件的形式,用 v-for
來跑子元件。
示範範例
單向數據流
前面有提到 props 由父元件往子元件傳遞資料是單向數據流,當父元件的資料更新的時候,所有子元件的 props 會更新到最新值,所以如果你在某個元件更改了 props 的資料,則會破壞子元件間的獨立狀態,Vue 會在控制台中示警。
這意味著你不能也不該在子元件中更改 props 的資料。
但是如果你要在子元件中操作運算 props 進來的資料,可以這樣做:
props 作為初始值,指定給一個新的變數
傳入的 props 要變成某個物件的屬性,再指給一個新的變數,這樣新的變數就可以自由操作運算,而不會去改到父層的資料。
示範範例
將傳入的 props 轉換,例如把他指定給一個 computed 去產生一個新的資料。
props 驗證
前面範例的 props 大多放在一個陣列之中,但是實務上,放入物件是比較好的做法,這樣做的同時可以把驗證的條件帶入 props 的屬性中,例如指定型別、設定預設值及是否為必須。
以下說明,取自 Vue 的官網: