跳至主要内容

[Vue] 元件-Props

TL;DR

參考資料

相關連結


定義Props

因為每個元件內各自的資料是獨立的

如果今天父元件內需要掛載一個子元件,而子元件想要取用到父元件的資料時,我們需要在子元件定義一個Props的屬性。

<div id="app">
<div class="p-5">
<h3>Props 靜態資料</h3>
<photo url="https://images.unsplash.com/photo-1605784401368-5af1d9d6c4dc?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80"></photo>

<h3>動態資源</h3>
<photo :url="imgUrl"></photo>
</div>
</div>
props口訣

Line:7 中,同時會撰props內所定義的變數名稱,以及父元件內的資料變數名稱。

口訣為:前內後外

寫在前面的為內層子元件所定義的props,後面為外層父元件的變數名稱。

Props的單向數據流

外層所傳入的資料,子元件是無法去修改值的。

<div id="app">
<div class="p-5">
{{`外層imgUrl的值:${imgUrl}`}}
<photo :url="imgUrl"></photo>
</div>
</div>

例外

單向數據流只限定第一層 因為陣列以及物件在傳遞的時候是使用傳址(call by reference)的方式去傳遞的。

所以雖然我們無法變更參考的記憶體位置,但是內層的資料我們可以更動,並且也會反映在父層元素上的資料中。

<div id="app">
<div class="p-5">
<!-- 修改photoarray元件內透過v-model所綁定的資料,仍然會改動到外層父元件內imgUrls陣列內資料的值 -->
{{`外層imgUrl的值:${imgUrls}`}}
<photoarray :url="imgUrls"></photoarray>
</div>
</div>

型別驗證

如果要在傳入資料時進行型別的驗證,需要將剛剛子元件中所定義的props陣列改為props物件

預備知識

如果不使用動態屬性v-bind,則一律傳入的值都是字串型別。

使用v-bind時,“”內的值會如同表達式,可以填入任何變數或是物件實字等等不同型別。

<div id="app">
<div class="p-5">
<!-- 直接使用money屬性則傳入的值300會顯示為字串 (傳入true也會顯示字串true) -->
<props-type money="300"></props-type>
<!-- 使用v-bind綁定時,則傳入值型別會相同 -->
<props-type :money="money"></props-type>
</div>
</div>
型別驗證不影響運作

就算型別驗證沒有通過,仍然可以正常執行js
只是會在開發者工具上看到Vue warning

codepen受限於環境故看不到 Vue warning

單一型別驗證

先前使用props時,是定義成一個陣列 (e.g:props:['url']) ,如果需要使用型別驗證的功能,則需要修改為物件。物件屬性名稱即為父元素傳入時所使用的屬性名稱:

<div id="app">
<div class="p-5">
<props-validation
:prop-a="fun"
>
</props-validation>
</div>
</div>
型別驗證之設定

單一型別驗證,可接受的型別包含:String, Number, Object, Boolean, Function

如設定為 null, undefined 會直接通過驗證

複數型別驗證

vue.js
const app = Vue.createApp({
data() {...}
});
app.component('props-validation', {
props: {
// 檢查如果是字串或是數字皆可通過
propB: [String, Number],
},
template: `...`
})
app.mount("#app");

必要值(required)

<div id="app">
<div class="p-5">
<!-- 需注意,這邊沒有使用v-bind
所以傳入的值required會為字串
(對應vue.js Line:7 型別檢查須為String) -->
<props-validation
prop-c="required"
>
</props-validation>
</div>
</div>

預設值(default)

在codepen範例中,雖然我們在<props-validation>內沒有撰寫prop-D的屬性,但是仍然有渲染出300的數值。

這是因為我們在預設值設定了300。

相對的,如果今天我們有傳入prop-D,則會套用傳入的數值。

<div id="app">
<div class="p-5">
<!-- 沒有撰寫任何prop-D的屬性,會套用預設值300 -->
<props-validation></props-validation>
</div>
</div>

自訂函式

等有用到再研究

<div id="app">
<div class="p-5">
<props-validation></props-validation>
<!-- { "money": 300 } -->
</div>
</div>

自訂驗證

如果需要自己定義驗證的規則,則可使用自訂驗證:

<div id="app">
<div class="p-5">
<props-validation
:prop-f="10000"
>
</props-validation>
</div>
</div>