Vue 3 實戰:掌握透傳屬性(Fallthrough Attributes)與 $attrs 的靈活運用
在開發 Vue 元件時,我們常會遇到這種情況:父元件傳入了一些屬性(如 class、id、disabled 或 @click),但子元件並沒有透過 defineProps 或 defineEmits 宣告它們。這些 未被宣告 的屬性就會變成 透傳屬性(Fallthrough Attributes),也就是 attrs。
預設情況下,Vue 會自動將這些屬性掛載到子元件的根元素(Root Element)上。
什麼是透傳屬性?
讓我們透過一個實戰範例來區分 props 與 attrs:
上(父)層
html
<MyButton class="primary" id="submit-btn" disabled text="送出" />下(子)層
js
defineProps({
text: {
type: String,
required: true,
default: "button",
},
});解析結果:
text: 因為有在defineProps宣告,它是props。class、id、disabled: 未被宣告,它們被歸類為 Attributes($attrs),並自動加在子元件的根元素上。。
進階控制:關閉自動透傳
有時候我們不希望 Vue 自動將屬性亂塞到根元素(例如根元素只是一個包裝層),這時可以透過 defineOptions 來關閉這個行為:
js
defineOptions({
inheritAttrs: false,
});核心觀念
當 inheritAttrs 設定為 false 後:
- 屬性就不會自動加到元件的根元素上。
- 開發者必須手動決定這些屬性(
$attrs)要放在哪裡,實現更精準的 UI 控制。
如何手動取得並分配 $attrs
當您關閉自動透傳後,可以透過以下兩種方式取得這些被遺忘的屬性:
在 Template 中直接使用 $attrs
這在想要將屬性轉發給內部特定元素時非常實用:
html
<p>{{ $attrs }}</p>在 Script 中使用 useAttrs()
如果您需要在邏輯中處理這些屬性,可以使用 Composition API:
vue
<script setup>
import { useAttrs } from "vue";
const attrs = useAttrs();
// 您可以觀察到所有的透傳屬性
console.log(attrs);
console.log(attrs.class);
console.log(attrs.id);
</script>
<template>
<ThroughIn v-bind="attrs" />
</template>特殊應用:透過 $attrs 向外傳遞事件
透傳屬性不僅包含資料,也包含 事件監聽器。若要在自定義元件內手動觸發父層傳來的點擊事件,必須注意命名方式(需使用 on 開頭):
html
<input type="button" value="Out 按鈕" @click="$attrs.onClick" />或是直接使用 v-bind 將所有屬性與事件一次性轉發給內層元件:
html
<InnerComponent v-bind="attrs" />總結
掌握透傳屬性是封裝高品質 UI 元件(如 Button、Input)的必經之路。透過 inheritAttrs: false 與 $attrs 的配合,您能確保元件的 HTML 結構乾淨,同時保有父元件傳入樣式與事件的靈活性。
