一文講解VUE3 defineProps的使用
defineProps是 Vue 3 組合式 API(script setup語法糖)中用于聲明組件 Props的編譯時(shí)宏(Compiler Macro)。它的核心作用是讓組件明確接收來自父組件的輸入?yún)?shù)(Props),并自動(dòng)處理 Prop 的響應(yīng)式綁定、類型校驗(yàn)與默認(rèn)值。
一、基礎(chǔ)概念
- 適用場景:僅在
<script setup>中使用(Vue 3.2+ 支持),無需手動(dòng)導(dǎo)入(編譯器會(huì)自動(dòng)識(shí)別)。 - 本質(zhì):返回一個(gè)只讀的響應(yīng)式對象,包含父組件傳遞的所有 Props(修改 Props 會(huì)觸發(fā)警告,需通過
emit反向通信)。 - 單向數(shù)據(jù)流:Props 是“父傳子”的單向綁定,子組件不能直接修改 Props,需通過事件通知父組件更新。
二、核心用法
defineProps支持三種聲明方式,覆蓋從簡單到復(fù)雜的場景:
1. 數(shù)組語法(簡單類型)
適用于僅需聲明 Prop 名稱的場景(無類型校驗(yàn)、默認(rèn)值或驗(yàn)證):
<script setup>
// 聲明兩個(gè) Prop:title(字符串)、count(數(shù)字)
const props = defineProps(['title', 'count'])
</script>
<template>
<h1>{{ title }}</h1>
<p>Count: {{ count }}</p>
</template>2. 對象語法(帶配置項(xiàng))
適用于需要類型校驗(yàn)、默認(rèn)值、必填性、自定義驗(yàn)證的場景。對象鍵為 Prop 名,值為配置對象:
<script setup>
const props = defineProps({
// 基礎(chǔ)類型校驗(yàn)(支持 String/Number/Boolean/Array/Object/Date/Function/Symbol)
title: {
type: String, // 類型(可多個(gè),如 [String, Number])
required: true, // 是否必填
default: 'Default Title' // 默認(rèn)值(僅當(dāng) required: false 時(shí)有效)
},
// 引用類型默認(rèn)值需用「工廠函數(shù)」返回(避免多實(shí)例共享同一引用)
list: {
type: Array,
default: () => [] // 工廠函數(shù)返回新數(shù)組
},
// 自定義驗(yàn)證函數(shù)(返回 true 表示合法)
status: {
validator(value) {
return ['active', 'inactive'].includes(value)
}
}
})
</script>配置項(xiàng)說明:
選項(xiàng) | 類型 | 說明 |
|---|---|---|
type | 原生構(gòu)造函數(shù)/數(shù)組 | 校驗(yàn) Prop 類型(如 String、Number,或多類型 [String, Number]) |
required | Boolean | 是否為必填 Prop |
default | 任意值/工廠函數(shù) | 默認(rèn)值(引用類型必須用工廠函數(shù)返回,避免共享) |
validator | Function | 自定義驗(yàn)證函數(shù)(參數(shù)為 Prop 值,返回布爾值) |
3. TypeScript 類型注解(推薦)
若項(xiàng)目使用 TypeScript,類型注解是最簡潔且類型安全的方式(替代對象語法的類型校驗(yàn))。需配合 defineProps的泛型參數(shù)使用:
<script setup lang="ts">
// 聲明 Props 類型(? 表示可選)
interface Props {
title?: string
count: number
list?: string[]
}
// 用泛型傳入類型
const props = defineProps<Props>()
</script>添加默認(rèn)值:
若需給 TS 類型的 Prop 設(shè)置默認(rèn)值,需配合 withDefaults輔助函數(shù)(Vue 3.2+ 支持):
<script setup lang="ts">
interface Props {
title?: string
count?: number
list?: string[]
}
// withDefaults 接收 defineProps 的結(jié)果 + 默認(rèn)值對象
const props = withDefaults(defineProps<Props>(), {
title: 'Hello Vue',
count: 0,
list: () => ['a', 'b'] // 引用類型仍需工廠函數(shù)
})
</script>三、關(guān)鍵特性
1. 響應(yīng)式訪問
defineProps返回的對象是響應(yīng)式的,可直接在模板或腳本中使用:
<script setup>
const props = defineProps({ msg: String })
console.log(props.msg) // 響應(yīng)式值(父組件修改時(shí)會(huì)更新)
</script>?? 注意:不要直接解構(gòu) Props(會(huì)丟失響應(yīng)性)!若需解構(gòu),需用 toRefs或 toRef轉(zhuǎn)換:
<script setup>
import { toRefs, toRef } from 'vue'
const props = defineProps({ msg: String, count: Number })
// 正確:保持響應(yīng)性
const { msg } = toRefs(props)
const countRef = toRef(props, 'count')
// 錯(cuò)誤:直接解構(gòu)會(huì)失去響應(yīng)性
// const { msg, count } = props
</script>2. 動(dòng)態(tài) Props
父組件傳遞的 Prop 若為響應(yīng)式數(shù)據(jù)(如 ref/reactive),子組件通過 defineProps接收后會(huì)自動(dòng)同步更新:
<!-- 父組件 -->
<script setup>
import { ref } from 'vue'
const parentMsg = ref('Hello from Parent')
</script>
<template>
<Child :msg="parentMsg" />
<button @click="parentMsg = 'Updated'">Change</button>
</template>
<!-- 子組件 -->
<script setup>
const props = defineProps({ msg: String })
</script>
<template>
<p>{{ msg }}</p> <!-- 點(diǎn)擊按鈕后會(huì)更新為 "Updated" -->
</template>3. 透傳 Attributes(v-bind="$attrs")
未被 defineProps聲明的 Prop 會(huì)被歸為透傳 Attributes(如 class、style或自定義未聲明的 Prop),可通過 $attrs訪問或自動(dòng)綁定到根元素:
<script setup>
defineProps(['title']) // 僅聲明 title
</script>
<template>
<!-- 未聲明的 Prop(如 class、data-id)會(huì)自動(dòng)綁定到 div -->
<div class="box" data-id="123">{{ title }}</div>
</template>若需手動(dòng)控制透傳,可使用 useAttrs()(組合式 API):
<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs() // 包含所有透傳 Attributes
</script>四、常見誤區(qū)與最佳實(shí)踐
- 不要在非
<script setup>中使用:defineProps是script setup的專屬宏,普通<script>需用export default { props: {} }(Vue 2 風(fēng)格)。 - 引用類型默認(rèn)值必須用工廠函數(shù):如
default: () => ({})而非default: {}(否則所有組件實(shí)例共享同一對象)。 - 優(yōu)先用 TypeScript 類型注解:比對象語法更簡潔,且能享受 TS 的類型提示與校驗(yàn)。
- 避免直接修改 Props:如需修改,應(yīng)通過
emit觸發(fā)父組件的事件(如@update:count="val => count = val")。
五、與 Vue 2 的區(qū)別
Vue 2 中用 export default { props: {} }聲明 Props,而 Vue 3 的 defineProps是編譯時(shí)優(yōu)化(無運(yùn)行時(shí)開銷),且更貼合組合式 API 的風(fēng)格。
總結(jié)
defineProps是 Vue 3 組件通信的核心工具之一,通過簡潔的語法實(shí)現(xiàn)了類型安全、響應(yīng)式綁定與靈活的校驗(yàn)配置。
到此這篇關(guān)于一文講解VUE3 defineProps的使用的文章就介紹到這了,更多相關(guān)VUE3 defineProps使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue3中defineProps的使用詳解
- Vue3之defineProps、defineEmits和defineExpose的使用及說明
- Vue3屬性值傳遞defineProps詳解
- Vue3中defineProps設(shè)置默認(rèn)值的方法實(shí)現(xiàn)
- vue3中defineProps及使用方法詳解
- vue3中defineEmits與defineProps的用法實(shí)例
- 解決vue3?defineProps?引入定義的接口報(bào)錯(cuò)
- 一文詳細(xì)聊聊vue3的defineProps、defineEmits和defineExpose
- 關(guān)于Vue3中defineProps用法圖文詳解
相關(guān)文章
如何解決Vue請求接口出現(xiàn)跨域問題Access-Control-Allow-Origin
這篇文章主要介紹了如何解決Vue請求接口出現(xiàn)跨域問題Access-Control-Allow-Origin,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
vue代碼分割的實(shí)現(xiàn)(codesplit)
這篇文章主要介紹了vue代碼分割的實(shí)現(xiàn)(codesplit),做了代碼分割后,會(huì)將代碼分離到不同的bundle中,然后進(jìn)行按需加載這些文件,需要的朋友可以參考下2018-11-11
vue子路由跳轉(zhuǎn)實(shí)現(xiàn)tab選項(xiàng)卡
這篇文章主要為大家詳細(xì)介紹了vue子路由跳轉(zhuǎn)實(shí)現(xiàn)tab選項(xiàng)卡,完成一個(gè)簡單的tab選項(xiàng)卡布局,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07
vue3+vite2實(shí)現(xiàn)動(dòng)態(tài)綁定圖片的優(yōu)雅解決方案
這篇文章主要為大家詳細(xì)介紹了vue3+vite2實(shí)現(xiàn)動(dòng)態(tài)綁定圖片的優(yōu)雅解決方案,文中的示例代碼簡潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-08-08

