vue中attrs和listeners的使用
# vue中$attrs和$listeners具体使用
# 一、v-bind="$attrs"的使用
在Vue中,组件上使用v-bind="$attrs"
是一种特殊的用法,它用于将父组件传递给子组件的非声明属性(non-prop attributes)传递给子组件的根元素。
当父组件向子组件传递属性时,子组件可以通过$attrs来获取这些未被声明为props的属性。
比如我们在封装组件的时候,有时候会基于原生的组件进行封装。但是我们不会将原生组件所有的属性都一一列出来,通过props进行传递。
这时候,可以在封装的时候,在原生的组件上声明v-bind="$attrs"
;这样在使用我们自己封装的组件的时候,可以给原生组件传特有的prop,不需要在我们封装的组件中一一申明;
MyButton:
<template>
<button
:class="buttonClass"
:style="buttonStyle"
@click="handleClick"
v-bind="$attrs"
>
<!-- v-bind="$attrs" 将所有未知的属性传递给原生button元素 -->
{{ label }}
</button>
</template>
<script>
export default {
name:'MyButton',
props: {
label: {
type: String,
required: true,
},
buttonClass: {
type: String,
default: "default-button-class",
},
buttonStyle: {
type: Object,
default: () => ({}),
},
},
methods: {
handleClick() {
this.$emit("click"); // 触发自定义的click事件
},
},
};
</script>
这样我们在使用组件的时候,可以传递组件没有定义的prop属性,这些属性是原生button上面的。比如下面的disabled属性就是如此!
使用自定义组件:
<template>
<div>
<MyButton
label="Click Me"
buttonClass="custom-button-class"
:disabled="true"
data-custom-attribute="Hello, Button!"
/>
</div>
</template>
<script>
import MyButton from './MyButton.vue';
export default {
components: {
MyButton,
},
data() {
return {
isButtonDisabled: true,
};
},
};
</script>
# 二、v-on=$listeners的使用
v-on=$listeners
提供了一种在组件之间传递事件监听器的便捷方法。通过$listeners,您可以将父组件上的所有事件监听器传递给子组件,使子组件能够在其内部的元素上注册这些事件监听器。
比如我们在基于原生或者其他UI组件库进行封装组件的时候,可以避免$emit
去传递事件,比如在使用elementUI的el-select组件的时候,我们可以通过这种方法直接绑定change事件!!
MyButton:
<template>
<button v-on="$listeners" :class="buttonClass">
{{ label }}
</button>
</template>
<script>
export default {
name:'MyButton',
inheritAttrs: false, // 防止$attrs被自动添加到根元素
props: {
label: {
type: String,
required: true,
},
buttonClass: {
type: String,
default: "default-button-class",
},
},
};
</script>
这样我们在使用自定义组件的时候,就可以不用emit去触发事件。通过使用$listeners,我们可以更加灵活地编写组件,将事件监听器传递给内部元素或子组件,从而使组件在行为上保持一致。
<template>
<div>
<MyButton
label="Click Me"
:class="customButtonClass"
@click="handleClick"
@mouseover="handleMouseOver"
/>
</div>
</template>
<script>
import MyButton from './MyButton.vue';
export default {
components: {
MyButton,
},
data() {
return {
customButtonClass: "custom-button-class",
};
},
methods: {
handleClick() {
alert("Button clicked!");
},
handleMouseOver() {
console.log("Mouse over the button!");
},
},
};
</script>