成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

在 Vue 中,使用 $attrs 構(gòu)建高級(jí)組件

開(kāi)發(fā) 前端
對(duì) $attrs 定義, Vue2 與 Vue3 是不一樣的,這里我們主要來(lái)介紹 Vue3 的版本:$attrs 對(duì)象包含了除組件所聲明的 props 和 emits 之外的所有其他 attribute,例如 class,style,v-on 監(jiān)聽(tīng)器等等。

這節(jié)課,我們來(lái)看下 Vue3 中的 $attrs 屬性。首先,我們會(huì)介紹它的用途以及它的實(shí)現(xiàn)與 Vue2 有哪些不兩同點(diǎn),并通過(guò)事例來(lái)加深對(duì)它的理解。

真正理解了 $attrs 屬性有助于我們構(gòu)建易于使用和可擴(kuò)展的高級(jí)組件

什么是 $attrs

對(duì) $attrs 定義, Vue2 與 Vue3 是不一樣的,這里我們主要來(lái)介紹 Vue3 的版本:

$attrs 對(duì)象包含了除組件所聲明的 props 和 emits 之外的所有其他 attribute,例如 class,style,v-on 監(jiān)聽(tīng)器等等。

$attrs 也可以被看作是一個(gè)安全網(wǎng),它可以捕獲任何我們沒(méi)有在組件中聲明的東西。我們考慮一個(gè)只有一個(gè)屬性和事件處理程序的組件,如下所示:

<template>
<h1 @click="$emit('custom', '改變標(biāo)題')">{{ title }}</h1>
</template>
<script>
export default {
name: 'Example',
props: ['title'],
emits: ['custom'],
}
</script>

如果在父組件中像下面這樣實(shí)例化上面的組件:

<template>
<div id="app">
<SimpleEvent
id="myId"
class="myClass"
data-cy="cypress-testing"
@blur="onBlur"
title="測(cè)試$attrs"
description="沒(méi)有聲明 props"
@custom="onCustom"
/>
</div>
</template>

<script setup>
import SimpleEvent from './components/Button.vue'

const onBlur = () => {
// todo
}
const onCustom = () => {
// todo
}

</script>

如果在組件中把 $attrs 打印出來(lái),我們會(huì)得到如下內(nèi)容:

{
id: 'myId',
class: 'myClass',
'data-cy': 'cypress-testing',
description: '沒(méi)有聲明 props',
onBlur: () => { // todo }
}

上面這些信息,感覺(jué)沒(méi)啥用,其實(shí)不然,我們下面會(huì)介紹如何利用這些信息。

attrs V3 vs $attrs V2

這小節(jié),我們來(lái)看下 Vue2 與 Vue3 中的 attrs 屬性的區(qū)別,先來(lái)看張圖:

圖片

與 Vue2 的區(qū)別主要有:

  • 自定義事件放在@listerner 對(duì)象中
  • 不包含class 屬性

而 Vue3 中的 attrs 對(duì)象包含了除組件所聲明的 props 和 emits 之外的所有其他 attribute,這有利于我們方便使用這些屬性。

下面我們來(lái)看些事例。

事例

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

首先我們創(chuàng)建一個(gè) Slider 組件,內(nèi)容如下所示:

<template>
<input
type="range"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
class="slider__input" />
</template>

<script>
export default {
name: "Slider-1",
props: {
modelValue: [Number, String],
}
};
</script>
<style lang="scss">
// 這里省略一堆樣式,自行看事例
</style>

上面代碼我們創(chuàng)建一個(gè) slider,還實(shí)現(xiàn)了一個(gè)雙向綁定。然后可以像下面這樣使用該組件:

<Slider-1 v-model="value" />

圖片

添加一些屬性

目前我們的 Slier 組件還很簡(jiǎn)單,不太符合實(shí)際情況。所以,我們添加幾個(gè)屬性(min, max, class, id, data-cy, @keydown 和 aria-label)。

<Slider-1
v-model="value"
min="0"
max="50"
class="blue_slider"
id="special_id"
data-cy="cypress-slider"
@keydown="() => true"
aria-label="Example slider"
/>

運(yùn)行后,通過(guò)控制檢查元素,我們可以看下,我們新加的屬性都被添加到了 HTML 元素上了:

圖片

看到這里,大家可能有疑問(wèn)了,既然所有的 "非屬性/事件" 屬性都已經(jīng)自動(dòng)應(yīng)用于內(nèi)部的HTML元素,為什么還要對(duì) $attrs 做這么大的介紹?

添加標(biāo)題和值

新增需求:作為一個(gè)滑塊的使用者,用戶(hù)希望能夠看到一個(gè)標(biāo)題,以及它在屏幕上顯示的數(shù)字形式的值。

我們?cè)谡{(diào)整一下 Slider 組件,內(nèi)容如下:

// Slider-2.vue

<template>
<div class="slider">
<h1>{{ title }}</h1>
<input
type="range"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
class="slider__input" />
<div>Value: {{ value }}</div>
</div>
</template>

<script>
export default {
name: "Slider-2",
props: {
modelValue: [Number, String]
title: [String],
value: [Number, String],
}
};
</script>

圖片

乍一看,好像沒(méi)啥問(wèn)題,但如果我們仔細(xì)觀察,可以看到有些東西是不對(duì)的。

首先,Slider 不是藍(lán)色的。第二,value 遠(yuǎn)遠(yuǎn)超過(guò)了50,最后,檢查一下HTML,會(huì)看到我們所有的額外屬性(min, max, data-cy)都被分配給了根元素,而不是我們的 input 元素。

解決上述問(wèn)題的最好方法是找到一種方法,將所有的屬性、類(lèi)、參數(shù)和事件直接 "應(yīng)用" 到 input  字段上,而不需我們手動(dòng)的一個(gè)個(gè)聲明。這就是 $attrs 出場(chǎng)的地方。

$attrs 救場(chǎng)

在本文的開(kāi)頭,我們介紹了 $attrs。它是一個(gè)存放所有 "未聲明"的屬性和事件的地方,而這正是我們需要解決的問(wèn)題。

要使用這個(gè)功能,我們只需將 $attrs 屬性應(yīng)用于一個(gè)或多個(gè)HTML元素,使用 v-bind 操作符。

<template>
<div class="slider">
<h1>{{ title }}</h1>
<input
type="range"
v-bind="$attrs"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
class="slider__input" />
<div>Value: {{ modelValue }}</div>
</div>
</template>

在組件中,我們使用 attrs 充當(dāng)橋梁,將所有的屬性(類(lèi)、屬性、屬性和自定義事件)復(fù)制到一個(gè)或多個(gè)元素上。Slider 組件又回到了正常模式上了。

圖片

還有一個(gè)問(wèn)題--我們添加的屬性不僅被分配給了 input 元素上,也分配給了 root元素。

通常情況下,這可能對(duì)界面沒(méi)啥影響,但有的屬性確實(shí)會(huì)生產(chǎn)一些副作用,下面,我們來(lái)解決這個(gè)問(wèn)題。

inheritAttrs: false

默認(rèn)情況下,任何被傳遞給組件的額外參數(shù)都會(huì)自動(dòng)應(yīng)用于根元素(以及所有有 $attrs 綁定的元素)。

為了關(guān)閉這個(gè)功能,并控制哪些元素可接受這個(gè)額外的屬性,我們可以使用一個(gè)名為 inheritAttrs 的標(biāo)志,并將其設(shè)置為false。

經(jīng)過(guò)這樣的改變,我們的HTML就變得漂亮且干凈了。所有的額外屬性都只作用于 input 元素。

責(zé)任編輯:武曉燕 來(lái)源: 大遷世界
相關(guān)推薦

2022-02-08 15:55:00

Vue組件庫(kù)Vue Demi

2020-03-25 18:23:07

Vue2Vue3組件

2019-05-20 15:08:07

PythonPyPI庫(kù)attrs

2020-02-21 11:08:24

瀏覽器HTML設(shè)計(jì)

2022-08-11 11:35:43

Vuev-model?表單

2023-04-26 15:17:33

Vue 3開(kāi)發(fā)前端

2023-07-28 13:55:40

便捷選項(xiàng)組件

2022-11-14 11:41:13

SVG開(kāi)發(fā)組件

2023-11-03 13:20:13

Kubernetes

2021-08-01 07:58:58

Vue 加載組件

2022-11-01 11:55:27

ReactVue3

2022-05-23 13:50:20

開(kāi)發(fā)封裝

2024-11-15 10:03:43

應(yīng)用模板Vue

2024-01-15 06:11:13

Go構(gòu)建器模式開(kāi)發(fā)

2016-09-19 21:37:58

vue特效組件Web

2009-06-18 09:42:52

SpringXFire構(gòu)建Web

2020-11-06 07:30:36

JS文件

2010-06-29 12:33:58

VoIP協(xié)議

2015-06-01 12:10:57

dockerhexo

2017-07-14 10:10:08

Vue.jsMixin
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩精品不卡 | 中文字幕在线人 | 狠狠干天天干 | 欧美一区二区三区视频在线播放 | 国产精品一区二区免费看 | 亚洲在线一区 | 国产免费拔擦拔擦8x高清 | 黑人精品欧美一区二区蜜桃 | 中文字幕人成乱码在线观看 | 国产一级片在线观看视频 | 免费在线观看成人 | 亚洲精品免费在线观看 | a毛片| 国产精品一级 | 国产高潮好爽受不了了夜色 | 国产精品毛片一区二区在线看 | 国产大片黄色 | 中文字幕av在线 | 在线观看中文字幕视频 | 九九99久久 | 97av视频在线 | 日本欧美大片 | 欧美激情久久久久久 | 国产三区在线观看视频 | 免费大黄视频 | 亚洲精品久久区二区三区蜜桃臀 | 久久国产精品一区 | av天天看| 欧美最猛性xxxxx亚洲精品 | 99久热 | 成人片免费看 | 亚洲444eee在线观看 | 日韩av在线免费 | 国产高清视频在线观看 | 狠狠干天天干 | 欧美精品在线一区二区三区 | 日韩a v在线免费观看 | 男人天堂99 | 在线免费观看黄色av | 一区二区三区国产 | 免费久|