記錄---用好了 defineProps 才叫會用 Vue3,90% 的寫法都錯了
????? 寫在開頭
點贊 + 收藏 === 學(xué)會??????
Vue 3 的
Composition API給開發(fā)者帶來了更強(qiáng)的邏輯組織能力,但很多人用defineProps的方式,依然停留在 Vue 2 的“Options 語法心智”。本質(zhì)上只是把props: {}拿出來“提前聲明”,并沒有真正理解它的運行機(jī)制、類型推導(dǎo)優(yōu)勢、默認(rèn)值處理方式、解構(gòu)陷阱等關(guān)鍵點。這篇文章不做語法搬運,而是用實戰(zhàn)視角,帶你了解:defineProps 到底該怎么寫,才是專業(yè)的 Vue3 寫法。
?? 為什么說你用錯了 defineProps?
我們先來看一個常見的 Vue3 組件寫法:
<script setup>
const props = defineProps({
title: String,
count: Number
})
</script>
你以為這就完事了?它只是基本寫法。但在真實業(yè)務(wù)中,我們往往會遇到:
- 需要傳默認(rèn)值
- 想要類型推導(dǎo)
- 解構(gòu) props 卻發(fā)現(xiàn)響應(yīng)性丟失
- TS 類型重復(fù)聲明,不夠優(yōu)雅
這些問題,defineProps 其實早就幫你解決了,只是你沒用對方式。
? 正確的三種 defineProps 寫法
① 寫法一:聲明式類型推導(dǎo)(推薦)
interface Props {
title: string
count?: number
}
const props = defineProps<Props>()
優(yōu)點:
- 自動獲得類型推導(dǎo)
- 在
<script setup lang="ts">中書寫自然 - 可配合
withDefaults補(bǔ)充默認(rèn)值
這是 Composition API 的推薦寫法,完全由 TypeScript 驅(qū)動,而不是運行時校驗。
② 寫法二:運行時代碼校驗(Options 式)
const props = defineProps({
title: {
type: String,
required: true
},
count: {
type: Number,
default: 0
}
})
優(yōu)點:
- 保留 Vue2 的 props 校驗邏輯
- 更適合 JS-only 項目(不使用 TS)
缺點:
- 類型推導(dǎo)不如泛型直觀
- 與
withDefaults不兼容
③ 寫法三:與 withDefaults 配合(實戰(zhàn)最常見)
const props = withDefaults(defineProps<{
title?: string
count?: number
}>(), {
title: '默認(rèn)標(biāo)題',
count: 1
})
優(yōu)勢是:
- 既能獲得類型推導(dǎo),又能寫默認(rèn)值
- 不會重復(fù)寫 default
- 比純 defineProps 更簡潔易維護(hù)
注意:withDefaults 只能配合泛型式 defineProps 使用,不能和對象式 props 寫法混用。
?? 高發(fā)誤區(qū)警告:你踩過幾個?
?? 誤區(qū) 1:直接解構(gòu) props,響應(yīng)性丟失
const { title, count } = defineProps<{ title: string, count: number }>()
上面的寫法會讓 title 和 count 成為普通變量,不是響應(yīng)式的。
解決方式:使用 toRefs
const props = defineProps<{ title: string, count: number }>()
const { title, count } = toRefs(props)
這樣才能在 watch(title, ...) 中有效監(jiān)聽變化。
?? 誤區(qū) 2:類型和默認(rèn)值重復(fù)聲明
const props = defineProps({
title: {
type: String as PropType<string>, // 寫了類型
default: 'Hello' // 又寫默認(rèn)值
}
})
在 TS 項目中,這種方式顯得繁瑣且不智能。建議直接用泛型 + withDefaults,讓 IDE 自動推導(dǎo)類型。
?? 誤區(qū) 3:沒有區(qū)分“開發(fā)期類型檢查” vs “運行時校驗”
Vue3 的 Props 有兩個模式:
- TypeScript 模式:靠 IDE + 編譯器
- Options 模式:在瀏覽器運行時報錯
實際推薦:生產(chǎn)環(huán)境靠 TypeScript 檢查即可,無需運行時 Props 校驗,提高性能。
?? defineProps 是真正的組件契約聲明
在 Vue3 的 <script setup> 中,defineProps 就是你和使用你組件的人之間的契約。
為什么說它是契約?
- 它聲明了組件的“輸入規(guī)范”
- 它決定了類型校驗、默認(rèn)值邏輯
- 它是組件文檔的第一手來源
你越是隨便寫它,越容易在團(tuán)隊協(xié)作時踩坑。
?? defineProps 的進(jìn)階技巧:你未必知道的幾個點
? 你可以在 defineProps 里使用類型別名
type Size = 'sm' | 'md' | 'lg'
withDefaults(defineProps<{
size?: Size
}>(), {
size: 'md'
})
這是讓 props.size 具備完整類型提示的關(guān)鍵方式。
? 配合 defineEmits 寫法更完整
const emit = defineEmits<{
(e: 'submit', value: number): void
(e: 'cancel'): void
}>()
這樣寫出的組件,輸入(props)+ 輸出(emit)都具備契約,可以被任何 IDE 精確識別。
? defineProps 寫法決定你能不能使用 Volar 的類型推導(dǎo)
很多人發(fā)現(xiàn) <MyComponent :title="xx" /> 里沒有類型提示,大概率是你組件沒有正確寫 defineProps 的泛型。保持結(jié)構(gòu)清晰,是讓 IDE 吃得飽的唯一方式。
?? 小結(jié):defineProps 不只是 props,它是組件健壯性的開端

正確思路是:在 TypeScript 項目中,盡可能采用 defineProps<T>() + withDefaults() 寫法,做到類型明確、默認(rèn)值清晰、響應(yīng)式安全。
?? 怎么判斷你是否“真的會用 defineProps”?
- ? 你寫了 defineProps 但 props 解構(gòu)不響應(yīng)
- ? 你寫 default 寫得很痛苦
- ? 你項目里 props 寫法風(fēng)格混亂
- ? 你的組件在 IDE 中沒有 props 自動補(bǔ)全
? 如果你能做到:
- 使用泛型 +
withDefaults - 保持 props 和 emits 的契約完整
- 清晰地類型提示和響應(yīng)性解構(gòu)
那恭喜你,是真的理解了 Vue3 的組件心智模型。
本文轉(zhuǎn)載于:https://juejin.cn/post/7513117108114473001
如果對您有所幫助,歡迎您點個關(guān)注,我會定時更新技術(shù)文檔,大家一起討論學(xué)習(xí),一起進(jìn)步。


浙公網(wǎng)安備 33010602011771號