在使用组件的时候,传入的事件,会默认传给组件的最外层标签上
例如:如下例子:定义了一个Button组件,在Button组件中未定义任何事件,但是在使用这个组件的时候传入的事件却可以使用,就是因为vue会把你传给这个组件上的所有事件,默认传给最外层的元素;
如下:click、focus、mouseover这些事件都传给了Button组件中的div元素
<template>
<div>
<Button @click="mm" @focus="mm" @mouseover="mm" size="normal">点击 </Button>
</div>
</template>
<script lang="ts">
import Button from "../lib/Button.vue";
export default {
components: { Button },
setup() {
const mm = () => {
console.log("hhhh");
};
return { mm };
},
};
</script>
>
Button.vue
<template>
<div>
<button>
<slot></slot>
</button>
</div>
</template>
如果想要让div不继承属性,可以用inheritAttrs:false,这样就继承那些属性了
<template>
<div>
<button>
<slot></slot>
</button>
</div>
</template>
<script lang="ts">
export default {
inheritAttrs: false,
};
</script>
如果想要让div里面的button绑定上这些属性,可以用v-bin=$attrs
<template>
<div>
<button v-bind="$attrs">
<slot></slot>
</button>
</div>
</template>
<script lang="ts">
export default {
inheritAttrs: false,
};
</script>
如果想要一部分绑定给button,一部分绑定给div呢,我们可以借助context.attrs
<template>
<div :size="size">
<button v-bind="rest">
<slot></slot>
</button>
</div>
</template>
<script lang="ts">
export default {
inheritAttrs: false,
setup(props, context) {
const { size, ...rest } = context.attrs;
return { size, rest };
},
};
</script>
总结:
- 默认所有属性都绑定到根元素
- 使用inheritAttrs:false可以取消默认绑定
- 使用$attrs或者context.attrs获取所有属性
- 使用v-bind='$attrs'批量绑定属性
- 使用const{size,...xxx}=context.attrs将属性分开
props与attrs的区别:
- props需要先声明才能获取值,而attrs则不用
- props声明过的属性,attrs里面不会在出现
- props不包含事件,attrs包含
- props支持string以外的类型,而attrs只有string类型