Vue Props
Props 是 Vue 中的一個配置選項。
透過 props,我們可以透過自定義屬性將資料傳遞給元件,這些屬性新增到元件的標籤上。
將資料傳遞給元件
還記得上一頁中所有三個元件都顯示“Apple”的例子嗎?透過 props,我們現在可以將資料傳遞給我們的元件,為它們提供不同的內容並使它們看起來不同。
讓我們建立一個簡單的頁面來顯示“Apples”、“Pizza”和“Rice”。
在主應用程式檔案 App.vue
中,我們建立自己的屬性“food-name”來透過 <food-item/>
元件標籤傳遞 prop。
App.vue
:
<template>
<h1>Food</h1>
<food-item food-name="Apples"/>
<food-item food-name="Pizza"/>
<food-item food-name="Rice"/>
</template>
<script></script>
<style>
#app > div {
border: dashed black 1px;
display: inline-block;
width: 120px;
margin: 10px;
padding: 10px;
background-color: lightgreen;
}
</style>
在元件內部接收資料
要接收從 App.vue
透過“food-item”屬性發送的資料,我們使用這個新的“props”配置選項。我們列出接收到的屬性,以便我們的元件 *.vue 檔案瞭解它們,現在我們可以在元件內部的任何地方以與使用資料屬性相同的方式使用 props。
FoodItem.vue
:
<script>
export default {
props: [
'foodName'
]
}
</script>
Props 屬性在 <template>
標籤中用連字元 -
分隔單詞(kebab-case),但在 JavaScript 中 kebab-case 是非法的。所以我們改用 camel Case 在 JavaScript 中寫屬性名,Vue 會自動識別!
最後,我們用 <div>
元素來顯示“Apples”、“Pizza”和“Rice”的例子看起來是這樣的
示例
App.vue
:
<template>
<h1>Food</h1>
<food-item food-name="Apples"/>
<food-item food-name="Pizza"/>
<food-item food-name="Rice"/>
</template>
FoodItem.vue
:
<template>
<div>
<h2>{{ foodName }}</h2>
</div>
</template>
<script>
export default {
props: [
'foodName'
]
}
</script>
<style></style>
執行示例 »
很快我們將看到如何將不同型別的資料作為 props 屬性傳遞給元件,但在那之前,讓我們透過描述每種食物來擴充套件我們的程式碼,並將食物 <div>
元素放在 Flexbox 容器內。
示例
App.vue
:
<template>
<h1>Food</h1>
<div id="wrapper">
<food-item
food-name="Apples"
food-desc="Apples are a type of fruit that grow on trees."/>
<food-item
food-name="Pizza"
food-desc="Pizza has a bread base with tomato sauce, cheese, and toppings on top."/>
<food-item
food-name="Rice"
food-desc="Rice is a type of grain that people like to eat."/>
</div>
</template>
<script></script>
<style>
#wrapper {
display: flex;
flex-wrap: wrap;
}
#wrapper > div {
border: dashed black 1px;
margin: 10px;
padding: 10px;
background-color: lightgreen;
}
</style>
FoodItem.vue
:
<template>
<div>
<h2>{{ foodName }}</h2>
<p>{{ foodDesc }}</p>
</div>
</template>
<script>
export default {
props: [
'foodName',
'foodDesc'
]
}
</script>
<style></style>
執行示例 »
布林 Props
透過傳遞不同資料型別的 props,我們可以實現不同的功能,並且我們能夠定義當元件從 App.vue
建立時如何給出屬性的規則。
讓我們新增一個新 prop“isFavorite”。它應該是一個布林 prop,值為 true
或 false
,這樣我們就可以直接使用 v-show
來顯示一個喜歡的印章 <img>
標籤,如果該食物被認為是喜歡的。
要傳遞字串以外的資料型別的 props,我們必須在要傳遞的屬性前加上 v-bind:
。
這就是我們從 App.vue
將布林值“isFavorite” prop 作為“is-favorite”屬性傳遞的方式
App.vue
:
<template>
<h1>Food</h1>
<p>My favorite food has a diploma image attached to it.</p>
<div id="wrapper">
<food-item
food-name="Apples"
food-desc="Apples are a type of fruit that grow on trees."
v-bind:is-favorite="true"/>
<food-item
food-name="Pizza"
food-desc="Pizza has a bread base with tomato sauce, cheese, and toppings on top."
v-bind:is-favorite="false"/>
<food-item
food-name="Rice"
food-desc="Rice is a type of grain that people like to eat."
v-bind:is-favorite="false"/>
</div>
</template>
我們在 FoodItem.vue
中接收布林值“isFavorite” prop,如果食物被認為是喜歡的,則顯示一個喜歡的印章
示例
FoodItem.vue
:
<template>
<div>
<h2>
{{ foodName }}
<img src="/img_quality.svg" v-show="isFavorite">
</h2>
<p>{{ foodDesc }}</p>
</div>
</template>
<script>
export default {
props: ['foodName','foodDesc','isFavorite']
}
</script>
<style>
img {
height: 1.5em;
float: right;
}
</style>
執行示例 »
圖片:要使上面示例中的圖片在您計算機上的本地專案中正常工作,請開啟上面的示例,右鍵單擊圖片,選擇“另存為影像...”並將其儲存在專案中的“public”資料夾中。


Props 介面
在上面的示例中,根據 FoodItem.vue
中的程式碼,我們無法確切知道我們收到了“isFavorite” prop,也無法確切知道它是否是布林值。為了幫助我們,我們可以定義接收的 props 的資料型別,我們可以設定 props 為必需的,我們甚至可以建立驗證函式來驗證我們接收到的 props。
定義我們接收的 props 可以作為文件供團隊中的其他人參考,如果我們定義的規則被打破,它會在控制檯中為我們提供警告。
Props 作為物件
在 FoodItem.vue
中,我們註釋掉了如何將 props 定義為陣列以便作為參考,而是將 props 定義在一個物件中。我們還可以定義每個 prop 的資料型別,除了 prop 名稱,如下所示
FoodItem.vue
:
<script>
export default {
// props: ['foodName','foodDesc','isFavorite']
props: {
foodName: String,
foodDesc: String,
isFavorite: Boolean
}
}
</script>
透過這樣定義 props,其他人可以檢視 FoodItem.vue
並輕鬆瞭解元件的預期。
如果一個元件是從父元素(在我們的例子中是 App.vue
)建立的,並且給定了一個錯誤資料型別的 prop,您會在控制檯中看到一個警告,如下所示

這樣的警告很有用,可以讓我們自己和他人知道一個元件沒有按預期使用,並告知是什麼出了問題,以便我們可以糾正錯誤。
必需的 Props
要告訴 Vue prop 是必需的,我們需要將 prop 定義為一個物件。讓我們將“foodName” prop 定義為必需的,如下所示
FoodItem.vue
:
<script>
export default {
// props: ['foodName','foodDesc','isFavorite']
props: {
foodName: {
type: String,
required: true
},
foodDesc: String,
isFavorite: Boolean
}
}
</script>
如果一個元件是從父元素(在我們的例子中是 App.vue
)建立的,並且沒有定義必需的 prop,您會在控制檯中看到一個警告,如下所示

這樣的警告很有用,可以讓我們自己和他人知道一個元件沒有按預期使用,並告知是什麼出了問題,以便我們可以糾正錯誤。
預設值
我們可以為 prop 設定預設值。
讓我們為“FoodItem”元件中的“foodDesc” prop 建立一個預設值,然後為米飯建立一個這樣的項,而不定義“foodDesc” prop
示例
App.vue
:
<template>
<h1>Food</h1>
<p>My favorite food has a diploma image attached to it.</p>
<div id="wrapper">
<food-item
food-name="Apples"
food-desc="Apples are a type of fruit that grow on trees."
v-bind:is-favorite="true"/>
<food-item
food-name="Pizza"
food-desc="Pizza has a bread base with tomato sauce, cheese, and toppings on top."
v-bind:is-favorite="false"/>
<food-item
food-name="Rice"
food-desc="Rice is a type of grain that people like to eat."
v-bind:is-favorite="false"/>
</div>
</template>
FoodItem.vue
:
<script>
export default {
props: {
foodName: {
type: String,
required: true
},
foodDesc: {
type: String,
required: false,
default: 'This is the default description.'
}
isFavorite: {
type: Boolean,
required: false,
default: false
}
}
}
</script>
執行示例 »
Props 驗證器函式
我們還可以定義一個驗證器函式來決定 prop 值是否有效。
這些驗證器函式必須返回 true 或 false。當驗證器返回 false 時,表示 prop 值無效。無效的 prop 值在以開發者模式執行頁面時會在瀏覽器控制檯中生成警告,該警告是有用的提示,可以確保元件按預期使用。
假設我們希望食物描述具有一定的長度,在 20 到 50 個字元之間。我們可以新增一個驗證器函式來確保提供的食物描述具有有效長度。
FoodItem.vue
:
<script>
export default {
props: {
foodName: {
type: String,
required: true
},
foodDesc: {
type: String,
required: false,
default: 'This is the default description.',
validator: function(value) {
if( 20<value.length && value.length<50 ) {
return true;
}
else {
return false;
}
}
}
isFavorite: {
type: Boolean,
required: false,
default: false
}
}
}
</script>
注意:如果您將上面的驗證器程式碼新增到您的本地專案中,您將在開發模式下收到一個警告,因為披薩的食物描述是 65 個字元,比驗證器函式允許的字元長 15 個。

修改 Props
當一個元件在父元素中建立時,我們不允許在子元素中更改接收到的 prop 的值。所以,在 FoodItem.vue
內部,我們不能更改從 App.vue
接收到的“isFavorite” prop 的值。prop 從父級是隻讀的,在我們的例子中,父級是 App.vue
。
但是,假設我們希望使用者能夠透過單擊按鈕來更改哪些食物被視為喜歡的。現在需要更改“isFavorite” prop,但我們不能這樣做,因為它被標記為只讀。
我們不允許更改“isFavorite”。這將生成一個錯誤。
methods: {
toggleFavorite() {
this.isFavorite = !this.isFavorite;
}
}
為了解決這個問題,我們可以使用 prop 來初始化 FoodItem.vue
內部的一個新資料值“foodIsFavorite”,如下所示
data() {
return {
foodIsFavorite: this.isFavorite
}
}
現在我們可以新增一個方法,以便使用者可以切換這個新的資料值
methods: {
toggleFavorite() {
this.foodIsFavorite = !this.foodIsFavorite;
}
}
我們還必須為每個食物項新增切換按鈕,並將 <img>
標籤中的 v-show
設定為依賴於新的資料屬性“foodIsFavorite”。為了使我們的示例更簡單,我們還將 props 宣告簡化為僅陣列。
示例
FoodItem.vue
:
<template>
<div>
<h2>
{{ foodName }}
<img src="/img_quality.svg" v-show="foodIsFavorite">
</h2>
<p>{{ foodDesc }}</p>
<button v-on:click="toggleFavorite">Favorite</button>
</div>
</template>
<script>
export default {
props: ['foodName','foodDesc','isFavorite'],
data() {
return {
foodIsFavorite: this.isFavorite
}
},
methods: {
toggleFavorite() {
this.foodIsFavorite = !this.foodIsFavorite;
}
}
}
</script>
<style>
img {
height: 1.5em;
float: right;
}
</style>
執行示例 »