首先需要弄清楚的是:
在vue中父类在使用子类组件时,默认将绑定事件传给了子类组件的根元素。
例:
有这样一个组件:
<template>
<div>
<button><slot/></button>
</div>
</template>
使用该组件:
<Button @click="xxx" @focus="yyy" size="small">I'm button</Button>
以上例子中,click、focus事件的作用范围是组件的根结点<div>
,而通常,我们是想在<button>
上绑定事件,所以要取消事件,然后再手动绑定到<button>
上。
- 在子类组件的选项中设置:
inheritAttrs:false
,组件的根元素就会取消继承,绑定事件无效。 - 事件无效后,需要将事件手动绑定到想要绑定的组件某元素上,即:
<div><button v-bind="$attrs"></button></div>
- $attrs
-
$attrs
:包含了在使用组件时设置的所有属性,包括绑定事件; -
$attrs
等同于setup
里面的context.attrs
。
而v-bind="$attrs
中,$attrs包含了size和绑定事件,需要分离出来:
那么:setup(props, context){ const {size, ...rest} = context.attrs return {size, rest} }
v-bind="rest"
<div><button v-bind="rest"></button></div>
-
- 总结
- 对于属性
size
而言,如果在组件中props
声明过size
,那么$attrs
里就不会出现size
了。 - 虽然
inheritAttrs:false
,但$attrs里面该有的还是有,只是绑定事件无效了,需要手动绑定一下。
- 对于属性
props和$attrs区别
通过以上,props和$attrs的区别显而易见。
-
props
是父类向子类传递并且需要子类主动接收的属性,当然props不包含事件; -
$attrs
默认是父类传递到子类根元素的属性,子类不用主动接收,会直接放在子类根元素上。 而$attrs
的这种默认行为,可以通过设置inheritAttrs:false
,这些默认行为将会被取消。