EP25 - 降級屬性

更新於 發佈於 閱讀時間約 1 分鐘
Fallthrough Attributes 感覺是一種特殊的屬性!
之前文章有提到過幾次了~要好好再研究清楚!
只是這屬性的英文應該是~fall throught 降級的意思?!!! 不是失敗的意思~

這個頁面假設您已經閱讀過「組件基礎」內容。對組件不熟悉,建議先閱讀該部分。

屬性繼承 - Attribute Inheritance

「降級屬性」是指傳遞給組件的屬性或 v-on 事件監聽器,但在接收組件的 props 或 emits 中沒有明確聲明。常見的例子包括 class、style 和 id 屬性。

當組件渲染一個單根元素時,降級屬性將自動添加到根元素的屬性中。例如,給定一個具有以下模板的 <MyButton> 組件:

<!-- <MyButton> 的模板 -->
<button>Click Me</button>

以及一個使用此組件的父組件:

<MyButton class="large" />

最終渲染的 DOM 將是:

<button class="large">Click Me</button>

在這裡,<MyButton> 沒有將 class 聲明為可接受的 prop。因此,class 被視為一個降級屬性,自動添加到 <MyButton> 的根元素中。

class 和 style 的合併 -class and style Merging

如果子組件的根元素已經有現有的 class 或 style 屬性,這些屬性將與從父組件繼承的 class 和 style 值合併。假設我們將前一個例子中 <MyButton> 的模板更改為:

<!-- <MyButton> 的模板 -->
<button class="btn">Click Me</button>

那麼最終渲染的 DOM 將變為:

<button class="btn large">Click Me</button>

v-on 監聽器繼承 - v-on Listener Inheritance

相同的規則適用於 v-on 事件監聽器:

<MyButton @click="onClick" />

click 監聽器將被添加到 <MyButton> 的根元素,即原生 <button> 元素上。當原生 <button> 被點擊時,將觸發父組件的 onClick 方法。如果原生 <button> 已經綁定了一個使用 v-on 的 click 監聽器,那麼兩個監聽器都會被觸發。

嵌套組件繼承 - Nested Component Inheritance

如果一個組件渲染另一個組件作為其根節點,例如,我們重構了 <MyButton> 以渲染 <BaseButton> 作為其根:

<!-- 渲染另一個組件的 <MyButton/> 的模板 -->
<BaseButton />

那麼 <MyButton> 接收到的降級屬性將自動轉發給 <BaseButton>

注意:

  • 被轉發的屬性不包括被聲明為 props 的任何屬性,或由 <MyButton> 聲明的事件的 v-on 監聽器——換句話說,聲明的 props 和監聽器已被 <MyButton>「消耗」。
  • 被轉發的屬性如果被 <BaseButton> 聲明,則可以作為 props 接受。

禁用屬性繼承 - Disabling Attribute Inheritance

如果您不希望組件自動繼承屬性,可以在組件選項中設置 inheritAttrs: false

自 3.3 版本以來,您也可以在 <script setup> 中直接使用 defineOptions

<script setup>
defineOptions({
inheritAttrs: false
})
// ...setup 邏輯
</script>

禁用屬性繼承的常見情境是當屬性需要應用於根節點之外的其他元素時。通過將 inheritAttrs 選項設置為 false,您可以完全控制降級屬性應該應用的位置。

這些降級屬性可以通過 $attrs 在模板表達式中直接訪問:

<span>降級屬性: {{ $attrs }}</span>

$attrs 對象包括所有未由組件的 props 或 emits 選項聲明的屬性(例如 class、style、v-on 監聽器等)。

一些注意事項:

  • 與 props 不同,降級屬性在 JavaScript 中保留其原始大小寫,因此像 foo-bar 這樣的屬性需要作為 $attrs['foo-bar'] 訪問。
  • @click 這樣的 v-on 事件監聽器將作為一個函數暴露在 $attrs 下。

使用我們在前一部分的 <MyButton> 組件示例——有時我們可能需要為樣式目的將實際的 <button> 元素包裹在額外的 <div> 中:

<div class="btn-wrapper">
<button class="btn">Click Me</button>
</div>

我們希望所有降級屬性(如 class 和 v-on 監聽器)應用於內部的 <button>,而不是外部的 <div>。我們可以通過設置 inheritAttrs: falsev-bind="$attrs" 來實現:

<div class="btn-wrapper">
<button class="btn" v-bind="$attrs">Click Me</button>
</div>

請記住,沒有參數v-bind 將對象的所有屬性綁定為目標元素的屬性。

多根節點上的屬性繼承 - Attribute Inheritance on Multiple Root Nodes

與單根節點的組件不同,具有多根節點的組件沒有自動的屬性降級行為。如果 $attrs 沒有明確綁定,將會發出運行時警告。

<CustomLayout id="custom-layout" @click="changeValue" />

如果 <CustomLayout> 有以下多根模板,將會發出警告,因為 Vue 無法確定將降級屬性應用到哪裡:

<header>...</header>
<main>...</main>
<footer>...</footer>

如果明確綁定了 $attrs,則警告將被抑制:

<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>

在 JavaScript 中訪問降級屬性 - Accessing Fallthrough Attributes in JavaScript

如果需要,您可以使用 useAttrs() API 在 <script setup> 中訪問組件的降級屬性:

<script setup>
import { useAttrs } from 'vue'

const attrs = useAttrs()
</script>

如果不使用 <script setup>,則 attrs 將作為 setup() 上下文的屬性暴露:

export default {
setup(props, ctx) {
// 降級屬性作為 ctx.attrs 暴露
console.log(ctx.attrs)
}
}

注意,雖然這裡的 attrs 對象始終反映最新的降級屬性,但它不是響應式的(出於性能考慮)。您無法使用監視器來觀察其變化。如果您需要響應性,請使用 prop。或者,您可以使用 onUpdated() 在每次更新時執行副作用。

為什麼看官方文件總有一種不知道他在幹嘛的感覺?
因為繼承放在屬性裡頭真的要多花一點時間理解~
組件之間屬性的關係蠻微妙的~
留言
avatar-img
留言分享你的想法!
avatar-img
卡關的人生
2會員
73內容數
分享生活趣事~
卡關的人生的其他內容
2024/11/10
Vue 提供了多種動畫技術來提升應用程式的互動性,包括基於 CSS 類別的動畫、基於狀態的動畫,以及使用監視器來動畫化數值。基於類別的動畫可通過動態添加 CSS 類別來觸發,像是觸發按鈕搖動效果。基於狀態的動畫則是透過樣式綁定,根據互動動態調整元素的外觀,例如根據滑鼠位置改變背景顏色。
Thumbnail
2024/11/10
Vue 提供了多種動畫技術來提升應用程式的互動性,包括基於 CSS 類別的動畫、基於狀態的動畫,以及使用監視器來動畫化數值。基於類別的動畫可通過動態添加 CSS 類別來觸發,像是觸發按鈕搖動效果。基於狀態的動畫則是透過樣式綁定,根據互動動態調整元素的外觀,例如根據滑鼠位置改變背景顏色。
Thumbnail
2024/11/09
Web Components 是一組網頁原生 API,允許開發者創建可重複使用的自訂元素。Vue 與 Web Components 是互補的技術,Vue 支援整合和創建自訂元素。
Thumbnail
2024/11/09
Web Components 是一組網頁原生 API,允許開發者創建可重複使用的自訂元素。Vue 與 Web Components 是互補的技術,Vue 支援整合和創建自訂元素。
Thumbnail
2024/11/08
Vue 建議使用模板構建應用程式,但在需要 JavaScript 的全程式化功能時,渲染函數可派上用場。渲染函數通過 h() 函數創建 vnode,h 是 hyperscript 的簡寫,能生成 HTML 的 JavaScript。
Thumbnail
2024/11/08
Vue 建議使用模板構建應用程式,但在需要 JavaScript 的全程式化功能時,渲染函數可派上用場。渲染函數通過 h() 函數創建 vnode,h 是 hyperscript 的簡寫,能生成 HTML 的 JavaScript。
Thumbnail
看更多
你可能也想看
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
自訂元件生成位置顧名思義就是可以指定部分HTML區塊渲染在特定的畫面上,即使在不同組件也能把A組件內的部分畫面,展現在B組件上,以下方程式舉例。
Thumbnail
自訂元件生成位置顧名思義就是可以指定部分HTML區塊渲染在特定的畫面上,即使在不同組件也能把A組件內的部分畫面,展現在B組件上,以下方程式舉例。
Thumbnail
Vue.js是一種基於MVVM的前端JavaScript框架,類似的框架有React、Angular等。 架設環境 安裝Visual Studio Code(https://code.visualstudio.com/) 安裝Node.js(https://nodejs.org/en/
Thumbnail
Vue.js是一種基於MVVM的前端JavaScript框架,類似的框架有React、Angular等。 架設環境 安裝Visual Studio Code(https://code.visualstudio.com/) 安裝Node.js(https://nodejs.org/en/
Thumbnail
2023 Vue直播班筆記 - 動態路由Props,接續之前的一般動態路由。分為 "寫死" 及 "彈性" 兩種。
Thumbnail
2023 Vue直播班筆記 - 動態路由Props,接續之前的一般動態路由。分為 "寫死" 及 "彈性" 兩種。
Thumbnail
Vue Router 及 具名視圖,擺脫以往切換依賴 CSS display:none 跟 display:block 互相配合,有時還得搭配 z-index 來調整層級跟 opacity 透明度的麻煩,而 Vue Router 完美的解決了這棘手的問題,且能客製頁面想要呈現的擺飾。
Thumbnail
Vue Router 及 具名視圖,擺脫以往切換依賴 CSS display:none 跟 display:block 互相配合,有時還得搭配 z-index 來調整層級跟 opacity 透明度的麻煩,而 Vue Router 完美的解決了這棘手的問題,且能客製頁面想要呈現的擺飾。
Thumbnail
這系列是我在 2023 六角學院 Vue作品實戰班的筆記,筆記以本人理解的方式記錄。此篇主題為 Slot Props 進階應用 ,其中包含單筆資料、多筆資料。
Thumbnail
這系列是我在 2023 六角學院 Vue作品實戰班的筆記,筆記以本人理解的方式記錄。此篇主題為 Slot Props 進階應用 ,其中包含單筆資料、多筆資料。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News