一文詳析vue3?Props的用法(父?jìng)髯?
在 Vue 3 中,Props(屬性)用于在組件之間傳遞數(shù)據(jù)。
Props的作用
- 傳參:Props 允許父組件向子組件傳遞數(shù)據(jù)。
- 類型檢查:Vue 允許在定義 Props 時(shí)指定數(shù)據(jù)的類型,這有助于在開發(fā)過(guò)程中進(jìn)行類型檢查,提前發(fā)現(xiàn)潛在的類型錯(cuò)誤。
- 設(shè)置默認(rèn)值:可以為 Props 設(shè)置默認(rèn)值。當(dāng)父組件沒有傳遞該 Prop 時(shí),子組件會(huì)使用默認(rèn)值進(jìn)行渲染。
Vue 中的 Props 遵循單向數(shù)據(jù)流原則,即父組件向子組件傳遞數(shù)據(jù),子組件不能直接修改父組件傳遞過(guò)來(lái)的 Prop。
父組件傳值給子組件
在父組件的模板中,可以使用屬性綁定的方式將數(shù)據(jù)傳遞給子組件(靜態(tài)傳值):
<ChildComponent title="哈嘿" />
可以使用變量或表達(dá)式來(lái)動(dòng)態(tài)地傳遞 Props:
<!-- 根據(jù)一個(gè)變量的值動(dòng)態(tài)傳入 --> <ChildComponent :title="title" /> <!-- 根據(jù)一個(gè)更復(fù)雜表達(dá)式的值動(dòng)態(tài)傳入 --> <ChildComponent :title="someCondition ? titleA : titleB" />
可以使用 v-bind 動(dòng)態(tài)綁定所有的 props:
可以將一個(gè)對(duì)象傳遞給 v-bind,這個(gè)對(duì)象的屬性將被用作組件的 props。
<template>
<ChildComponent v-bind="obj" />
</template>
<script setup lang="ts">
import ChildComponent from './ChildComponent.vue';
import { reactive } from 'vue'
let obj = reactive({
message: 'Hello',
count: 5
})
</script>
<ChildComponent v-bind="obj" /> 等價(jià)于:
<ChildComponent :message="message" :count="count" />
聲明 Props
- 使用
defineProps函數(shù):- 在
<script setup>語(yǔ)法中,可以直接使用defineProps函數(shù)來(lái)聲明組件接收的 Props。 - 在 Vue 3 中,基于類型的聲明通常用于組合式 API 。
- 在
<script setup lang="ts">
import { defineProps } from 'vue';
// 字符串?dāng)?shù)組形式
const props = defineProps(['message', 'count']);
</script>
在這個(gè)例子中,聲明了兩個(gè) Props:message 和count 。
可以使用對(duì)象字面量的方式來(lái)聲明 Props:
<script setup lang="ts">
import { defineProps } from 'vue';
const props = defineProps({
message: String,
count: Number,
});
</script>
在這個(gè)例子中,聲明了兩個(gè) Props:message 是字符串類型,count 是數(shù)字類型。通過(guò)類型注解,TypeScript 可以在開發(fā)過(guò)程中進(jìn)行類型檢查,確保傳入的 props 值符合預(yù)期的類型。
在 <script setup> 語(yǔ)法中,使用 defineProps 函數(shù)結(jié)合類型注解來(lái)進(jìn)行基于類型的聲明。
如果項(xiàng)目沒有使用 TypeScript,就無(wú)法使用基于類型的聲明進(jìn)行聲明。
基于類型的聲明可以在開發(fā)過(guò)程中利用 TypeScript 的類型檢查機(jī)制,提前發(fā)現(xiàn)類型錯(cuò)誤。
- 在選項(xiàng)式 API 中(沒有使用
<script setup>語(yǔ)法糖),props 是通過(guò)props選項(xiàng)進(jìn)行聲明的。- 必須要用
props選項(xiàng)聲明組件接收的Props,在setup()的props參數(shù)里,才有Props數(shù)據(jù)。 - 在 Vue 3 中,運(yùn)行時(shí)聲明通常用于選項(xiàng)式 API。
- 必須要用
export default {
props: ['message'],
setup(props) {
// setup() 接收 props 作為第一個(gè)參數(shù)
console.log(props.message)
}
}
必須要用props選項(xiàng)聲明組件接收的Props。如果沒有 props: ['message']:
export default {
setup(props) {
// 報(bào)錯(cuò): 類型“LooseRequired<{} & {}>”上不存在屬性“message”。
console.log(props.message)
}
}
通過(guò)在組件選項(xiàng)對(duì)象中直接定義 props 屬性來(lái)進(jìn)行運(yùn)行時(shí)聲明:
export default {
props: {
message: String,
count: Number,
},
setup() {}
// 組件的其他選項(xiàng)和邏輯
};
在這個(gè)例子中,message 被聲明為字符串類型的 Prop,count 被聲明為數(shù)字類型的 Prop。這種方式在運(yùn)行時(shí),Vue 會(huì)根據(jù)聲明的類型對(duì)傳入的 Props 進(jìn)行驗(yàn)證。
運(yùn)行時(shí)聲明通常在不需要進(jìn)行嚴(yán)格類型檢查或者需要更靈活地處理 Props 的情況下使用。它主要依賴于 Vue 的運(yùn)行時(shí)機(jī)制來(lái)處理 Props 的傳遞和驗(yàn)證。
傳遞給 defineProps() 的參數(shù)和提供給 props 選項(xiàng)的值是相同的,本質(zhì)上都是在使用 prop 選項(xiàng)。
Props 的驗(yàn)證
Props 驗(yàn)證的主要目的是確保組件接收到的數(shù)據(jù)符合預(yù)期的格式和類型。
類型驗(yàn)證
- 可以指定 Props 的類型,如
String、Number、Boolean、Array、Object等。 - 也可以是函數(shù)類型
Function、自定義類型。
<script setup lang="ts">
import { defineProps } from 'vue';
// 定義一個(gè)接口作為自定義類型
interface MyCustomType{
property1: string;
property2: number;
}
const props = defineProps({
name: String,
age: Number,
hobbies: Array,
address: Object,
customType: MyCustomType, // 自定義類型
onButtonClick: Function // 函數(shù)類型
});
</script>
確保父組件傳遞給子組件的Props值與聲明的類型一致,避免類型錯(cuò)誤。
必需性
- 可以指定 Props 是否為必需,如果為必需,則必須在父組件中傳入。
<script setup lang="ts">
import { defineProps } from 'vue';
const props = defineProps({
message: {
type: String,
required: true
}
});
</script>
在這個(gè)例子中,message 是必需的 Prop,如果父組件沒有傳遞 message ,則會(huì)拋出警告。
自定義驗(yàn)證
- 可以使用 validator 函數(shù)進(jìn)行自定義驗(yàn)證。
<script setup lang="ts">
import { defineProps } from "vue";
let props = defineProps({
b: {
type: Number,
validator: (value: number) => {
return value >= 0; // 自定義驗(yàn)證,確保寬度非負(fù)
}
}
})
console.log(props)
</script>
在這個(gè)例子中,b 使用了自定義驗(yàn)證函數(shù),確保b 的值不為負(fù)數(shù)。
在父組件傳入b = -10,瀏覽器控制臺(tái)輸出警告:

默認(rèn)值
可以為 Props 設(shè)置默認(rèn)值,當(dāng)父組件沒有傳遞該 Prop 時(shí),子組件會(huì)使用默認(rèn)值進(jìn)行渲染。
<script setup lang="ts">
import { defineProps } from 'vue';
const props = defineProps({
message: {
type: String,
default: 'Hello, Vue 3!',
},
count: {
type: Number,
default: 0,
},
});
</script>
在這個(gè)例子中,message 的默認(rèn)值為 'Hello, Vue 3!',count 的默認(rèn)值為 0。
withDefaults
在 Vue 3 中,withDefaults 是一個(gè)用于為 defineProps 定義的 props 設(shè)置默認(rèn)值的函數(shù)。
withDefaults 參數(shù)說(shuō)明:
withDefaults的第一個(gè)參數(shù)是defineProps的返回值,它表示組件接收的 props 對(duì)象。- 第二個(gè)參數(shù)是一個(gè)對(duì)象,其中的鍵對(duì)應(yīng)于 props 的名稱,值是相應(yīng)的默認(rèn)值。
- 默認(rèn)值是通過(guò)函數(shù)返回的。
假設(shè)有一個(gè)組件,定義了一些 props,并且希望為其中一些 props 設(shè)置默認(rèn)值:
<template>
<div>{{ props.message }}</div>
<div>{{ props.count }}</div>
</template>
<script setup lang="ts">
import { defineProps, withDefaults } from 'vue';
// 定義了一個(gè)接口 PropsInter 來(lái)描述組件的 props 結(jié)構(gòu)
interface PropsInter {
message: string;
count: number;
obj: { a: number; b: number; };
arr: string[];
}
const props = withDefaults(defineProps<PropsInter>(), {
message: 'Hello, Vue 3!',
count: 0,
obj: () => {
return { a: 10, b: 5 }
},
arr: () => return [ 'item1', 'item2' ]
});
</script>
Boolean 類型轉(zhuǎn)換
當(dāng)聲明為 Boolean 類型的 props 時(shí),有特別的類型轉(zhuǎn)換規(guī)則,以便更貼近原生的 boolean attributes 的行為。
- 當(dāng)一個(gè) prop 明確被聲明為布爾類型時(shí),真值會(huì)被轉(zhuǎn)換為
true,假值會(huì)被轉(zhuǎn)換為false:- 當(dāng)父組件傳遞一個(gè)真值(如
true、字符串"true"、數(shù)字1等)時(shí),該 prop 將被轉(zhuǎn)換為true。 - 當(dāng)父組件傳遞一個(gè)假值(如
false、字符串"false"、數(shù)字0、空字符串""、null、undefined等)時(shí),該 prop 將被轉(zhuǎn)換為false。
- 當(dāng)父組件傳遞一個(gè)真值(如
在子組件中:
defineProps({
disabled: Boolean
})
在父組件中:
<!-- 等同于傳入 :disabled="true" --> <MyComponent disabled /> <!-- 等同于傳入 :disabled="false" --> <MyComponent />
- 當(dāng)一個(gè) prop 被聲明為允許多種類型時(shí),聲明順序會(huì)影響 Boolean 轉(zhuǎn)換規(guī)則是否適用:
- 當(dāng)同時(shí)允許字符串和布爾類型時(shí),如果布爾類型出現(xiàn)在字符串類型之前,Boolean 轉(zhuǎn)換規(guī)則才適用。
const props = defineProps({
myProp: [Boolean, String],
});
如果父組件傳遞 "true",這個(gè)值將被轉(zhuǎn)換為布爾值 true。如果傳遞 "false",將被轉(zhuǎn)換為布爾值 false。其他字符串值將保持為字符串。
但是,如果聲明順序是 [String, Boolean],那么 "true" 和 "false" 將被視為字符串,而不會(huì)進(jìn)行布爾類型的轉(zhuǎn)換。
這種邊緣情況可能會(huì)導(dǎo)致在不同的聲明順序下,相同的輸入值被解釋為不同的類型。
使用 Props
在父組件的模板中傳值給子組件:
<ChildComponent title="哈嘿" />
在子組件的模板中,可以直接使用定義的 Props:
<template>
<div>{{ title }}</div>
</template>
<script setup lang="ts" name="ChildComponent">
import { defineProps } from "vue";
defineProps(['title'])
// console.log(title) // 報(bào)錯(cuò):找不到名稱“title”。
</script>
在模板中,可以直接使用title。
console.log(title) 報(bào)錯(cuò):找不到名稱“title”。
這是因?yàn)?code>title 并沒有被直接聲明為一個(gè)可用的變量。
在 Vue 3 的 <script setup> 中,defineProps 的返回值是一個(gè)包含傳入的 props 的對(duì)象。
如果想要在組件中使用 title ,需要通過(guò)defineProps的返回值來(lái)讀取:
<template>
<div>{{ props.title }}</div>
</template>
<script setup lang="ts" name="ChildComponent">
import { defineProps } from "vue";
// 只接收title屬性
let props = defineProps(['title'])
console.log(props)
if(props.title) {
console.log(props.title)
}
</script>
defineProps 返回一個(gè)對(duì)象 props,props 對(duì)象中包含了 title 屬性,可以通過(guò) props.title 的方式來(lái)訪問和使用這個(gè) prop 的值。

defineProps 的返回值是一個(gè)包含組件接收的 props 的只讀對(duì)象:
- 返回的
props對(duì)象是只讀的。 - 返回的
props對(duì)象包含了組件所有接收的東西:父組件傳遞給當(dāng)前組件的所有被組件明確聲明為 props 的屬性。- 必須在
defineProps中顯式的接收父組件傳遞的屬性。假如父組件傳了幾個(gè)屬性,比如<ChildComponent title="哈嘿" id="id12345" />,子組件defineProps(['title'])只接收title屬性,不會(huì)接收id屬性。
- 必須在
- 在組件內(nèi)部不能直接修改
props對(duì)象的屬性值。
實(shí)戰(zhàn)演練
在types/index.ts定義一個(gè)PersonInter接口:
// 定義一個(gè)接口,用于限制對(duì)象的具體屬性
// 接口在 TypeScript 中用于定義一種契約,確保實(shí)現(xiàn)該接口的對(duì)象都具有相同的結(jié)構(gòu)。
export interface PersonInter {
id: string;
name: string;
age: number;
}
在父組件有一個(gè)person傳遞給子組件:
<template>
<div>
<ChildComponent :personList="personList" />
</div>
</template>
<script setup lang="ts" name="Person">
// 在 TypeScript 中,import type 語(yǔ)法用于僅導(dǎo)入類型信息而不導(dǎo)入實(shí)際的值或函數(shù)。
// 使用 import type 導(dǎo)入的類型信息僅在類型檢查時(shí)使用,不會(huì)在運(yùn)行時(shí)產(chǎn)生任何影響。
import type { PersonInter } from '@/types';
import { reactive } from 'vue';
import ChildComponent from './ChildComponent.vue';
let personList = reactive<PersonInter>({
id: 'person001',
name: 'John',
age: 18
});
</script>
子組件:
<template>
<div>{{ person.name }}</div>
</template>
<script setup lang="ts" name="ChildComponent">
import type { PersonInter } from '@/types';
import { defineProps } from "vue";
// 只接收person
let props = defineProps(['person'])
console.log(props)
// 接收person+類型限制
let props = defineProps<{ person: PersonInter }>()
// 接收person+類型限制+限制必要性+默認(rèn)值
// ?表示不必傳,父組件可傳可不傳,如果父組件不傳,則使用默認(rèn)值
// 指定默認(rèn)值需要使用withDefaults
withDefaults(defineProps<{ person?: PersonInter }>(), {
person: () => {
return { id: 'person000', name: 'Alice', age: 18 }
}
})
</script>
let props = defineProps(['person'])只接收person,對(duì)person沒有任何限制。父組件可以給person賦任意類型的值。defineProps<{ person: PersonInter }>(): 通過(guò)泛型參數(shù)指定了props的結(jié)構(gòu)。具體來(lái)說(shuō),定義了一個(gè)名為person的 prop,其類型為PersonInter。defineProps<{ person?: PersonInter }>():- 使用泛型參數(shù)指定了
props的結(jié)構(gòu)。定義了一個(gè)名為person的 prop,其類型為PersonInter。 - 后面的問號(hào)
?表示這個(gè) prop 是可選的,即父組件可以選擇是否傳遞這個(gè) prop。
- 使用泛型參數(shù)指定了
總結(jié)
到此這篇關(guān)于vue3 Props用法(父?jìng)髯?的文章就介紹到這了,更多相關(guān)vue3 Props用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Ant-design-vue Table組件customRow屬性的使用說(shuō)明
這篇文章主要介紹了Ant-design-vue Table組件customRow屬性的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
Vue中對(duì)iframe實(shí)現(xiàn)keep alive無(wú)刷新的方法
這篇文章主要介紹了Vue中對(duì)iframe實(shí)現(xiàn)keep alive無(wú)刷新的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
vue :style設(shè)置背景圖片方式backgroundImage
這篇文章主要介紹了vue :style設(shè)置背景圖片方式backgroundImage,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
詳解auto-vue-file:一個(gè)自動(dòng)創(chuàng)建vue組件的包
這篇文章主要介紹了auto-vue-file:一個(gè)自動(dòng)創(chuàng)建vue組件的包,需要的朋友可以參考下2019-04-04
react+?ts?vite搭建及二次封裝請(qǐng)求的過(guò)程解析
這篇文章主要介紹了react+?ts?vite搭建及二次封裝請(qǐng)求,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04

