哦哇資訊網

在 Vue 中,使用 $attrs 構建高階元件

由 前端小智 發表于 美食2022-12-27

這節課,我們來看下 Vue3 中的

$attrs

屬性。首先,我們會介紹它的用途以及它的實現與 Vue2 有哪些不兩同點,並透過事例來加深對它的理解。

真正理解了

$attrs

屬性有助於我們構建易於使用和可擴充套件的高階元件

什麼是$attrs

$attrs

定義, Vue2 與 Vue3 是不一樣的,這裡我們主要來介紹 Vue3 的版本:

$attrs 物件包含了除元件所宣告的 props 和 emits 之外的所有其他 attribute,例如 class,style,v-on 監聽器等等。

$attrs

也可以被看作是一個安全網,它可以捕獲任何我們沒有在元件中宣告的東西。我們考慮一個只有一個屬性和事件處理程式的元件,如下所示:

如果在父元件中像下面這樣例項化上面的元件:

如果在元件中把

$attrs

打印出來,我們會得到如下內容:

{ id: ‘myId’, class: ‘myClass’, ‘data-cy’: ‘cypress-testing’, description: ‘沒有宣告 props’, onBlur: () => { // todo } }

上面這些資訊,感覺沒啥用,其實不然,我們下面會介紹如何利用這些資訊。

attrs V3 vs $attrs V2

這小節,我們來看下 Vue2 與 Vue3 中的

attrs

屬性的區別,先來看張圖:

與 Vue2 的區別主要有:

自定義事件放在

@listerner

物件中

不包含

class

屬性

而 Vue3 中的

attrs

物件包含了除元件所宣告的

props

emits

之外的所有其他

attribute

,這有利於我們方便使用這些屬性。

下面我們來看些事例。

事例

事例地址:https://stackblitz。com/edit/vue-slider-listener-example?file=src/components/Slider。vue

首先我們建立一個 Slider 元件,內容如下所示:

上面程式碼我們建立一個

slider

,還實現了一個雙向繫結。然後可以像下面這樣使用該元件:

新增一些屬性

目前我們的 Slier 元件還很簡單,不太符合實際情況。所以,我們新增幾個屬性(

min

max

class

id

data-cy

@keydown

aria-label

)。

true” aria-label=“Example slider” />

執行後,透過控制檢查元素,我們可以看下,我們新加的屬性都被新增到了 HTML 元素上了:

看到這裡,大家可能有疑問了,既然所有的 “非屬性/事件” 屬性都已經自動應用於內部的HTML元素,為什麼還要對

$attrs

做這麼大的介紹?

新增標題和值

新增需求:作為一個滑塊的使用者,使用者希望能夠看到一個標題,以及它在螢幕上顯示的數字形式的值。

我們在調整一下 Slider 元件,內容如下:

// Slider-2。vue

乍一看,好像沒啥問題,但如果我們仔細觀察,可以看到有些東西是不對的。

首先,Slider 不是藍色的。第二,

value

遠遠超過了50,最後,檢查一下HTML,會看到我們所有的額外屬性(

min, max, data-cy

)都被分配給了根元素,而不是我們的

input

元素。

解決上述問題的最好方法是找到一種方法,將所有的屬性、類、引數和事件直接 “應用” 到 input 欄位上,而不需我們手動的一個個宣告。這就是

$attrs

出場的地方。

$attrs 救場

在本文的開頭,我們介紹了

$attrs

。它是一個存放所有 “未宣告”的屬性和事件的地方,而這正是我們需要解決的問題。

要使用這個功能,我們只需將

$attrs

屬性應用於一個或多個HTML元素,使用

v-bind

運算子。

在元件中,我們使用

attrs

充當橋樑,將所有的屬性(類、屬性、屬性和自定義事件)複製到一個或多個元素上。Slider 元件又回到了正常模式上了。

還有一個問題——我們新增的屬性不僅被分配給了

input

元素上,也分配給了

root

元素。

通常情況下,這可能對介面沒啥影響,但有的屬性確實會生產一些副作用,下面,我們來解決這個問題。

inheritAttrs: false

預設情況下,任何被傳遞給元件的額外引數都會自動應用於根元素(以及所有有

$attrs

繫結的元素)。

為了關閉這個功能,並控制哪些元素可接受這個額外的屬性,我們可以使用一個名為

inheritAttrs

的標誌,並將其設定為

false

經過這樣的改變,我們的HTML就變得漂亮且乾淨了。所有的額外屬性都只作用於

input

元素。

TAG: attrs屬性元件我們Slider