本文首发于微信公众号:大迁世界, 我的微信:qq449245884,我会第一工夫和你分享前端行业趋势,学习路径等等。
更多开源作品请看 GitHub https://github.com/qq449245884/xiaozhi,蕴含一线大厂面试残缺考点、材料以及我的系列文章。
这节课,咱们来看下 Vue3 中的 $attrs
属性。首先,咱们会介绍它的用处以及它的实现与 Vue2 有哪些不两同点,并通过事例来加深对它的了解。
真正了解了 $attrs
属性有助于咱们构建易于应用和可扩大的高级组件
什么是 $attrs
对 $attrs
定义,Vue2 与 Vue3 是不一样的,这里咱们次要来介绍 Vue3 的版本:
$attrs 对象蕴含了除组件所申明的 props 和 emits 之外的所有其余 attribute,例如 class,style,v-on 监听器等等。
$attrs
也能够被看作是一个安全网,它能够捕捉任何咱们没有在组件中申明的货色。咱们思考一个只有一个属性和事件处理程序的组件,如下所示:
<template>
<h1 @click="$emit('custom',' 扭转题目 ')">{{title}}</h1>
</template>
<script>
export default {
name: 'Example',
props: ['title'],
emits: ['custom'],
}
</script>
如果在父组件中像上面这样实例化下面的组件:
<template>
<div id="app">
<SimpleEvent
id="myId"
class="myClass"
data-cy="cypress-testing"
@blur="onBlur"
title="测试 $attrs"
description="没有申明 props"
@custom="onCustom"
/>
</div>
</template>
<script setup>
import SimpleEvent from './components/Button.vue'
const onBlur = () => {// todo}
const onCustom = () => {// todo}
</script>
如果在组件中把 $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/v…
首先咱们创立一个 Slider 组件,内容如下所示:
<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>
下面代码咱们创立一个 slider
,还实现了一个双向绑定。而后能够像上面这样应用该组件:
<Slider-1 v-model="value" />
增加一些属性
目前咱们的 Slier 组件还很简略,不太符合实际状况。所以,咱们增加几个属性(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"
/>
运行后,通过管制查看元素,咱们能够看下,咱们新加的属性都被增加到了 HTML 元素上了:
看到这里,大家可能有疑难了,既然所有的 “ 非属性 / 事件 ” 属性都曾经主动利用于外部的 HTML 元素,为什么还要对 $attrs
做这么大的介绍?
增加题目和值
新增需要:作为一个滑块的使用者,用户心愿可能看到一个题目,以及它在屏幕上显示的数字模式的值。
咱们在调整一下 Slider 组件,内容如下:
// 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>
乍一看,如同没啥问题,但如果咱们仔细观察,能够看到有些货色是不对的。
首先,Slider 不是蓝色的。第二,value
远远超过了 50,最初,检查一下 HTML,会看到咱们所有的额定属性(min, max, data-cy
)都被调配给了根元素,而不是咱们的 input
元素。
解决上述问题的最好办法是找到一种办法,将所有的属性、类、参数和事件间接 “ 利用 ” 到 input 字段上,而不需咱们手动的一个个申明。这就是 $attrs
出场的中央。
$attrs 救场
在本文的结尾,咱们介绍了 $attrs
。它是一个寄存所有 “ 未声明 ” 的属性和事件的中央,而这正是咱们须要解决的问题。
要应用这个性能,咱们只需将 $attrs
属性利用于一个或多个 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
充当桥梁,将所有的属性(类、属性、属性和自定义事件)复制到一个或多个元素上。Slider 组件又回到了失常模式上了。
还有一个问题 – 咱们增加的属性不仅被调配给了 input
元素上,也调配给了 root
元素。
通常状况下,这可能对界面没啥影响,但有的属性的确会生产一些副作用,上面,咱们来解决这个问题。
inheritAttrs: false
默认状况下,任何被传递给组件的额定参数都会主动利用于根元素(以及所有有 $attrs
绑定的元素)。
为了敞开这个性能,并管制哪些元素可承受这个额定的属性,咱们能够应用一个名为 inheritAttrs
的标记,并将其设置为 false
。
通过这样的扭转,咱们的 HTML 就变得丑陋且洁净了。所有的额定属性都只作用于 input
元素。
编辑中可能存在的 bug 没法实时晓得,预先为了解决这些 bug, 花了大量的工夫进行 log 调试,这边顺便给大家举荐一个好用的 BUG 监控工具 Fundebug。
交换
有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。