vue3透传Attributes

425 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情juejin.cn/post/714765…

Attributes继承

“透传attribute”指的是传递给一个组件,却没有被该组件声明为props或emits的attribute或者v-on事件监听器。最常见的例子就是class、style和id。
当一个组件以单个元素为根做渲染时,透传的attribute会自动添加到该根元素上例如一个子组件身上只有一个根元素div:
HelloWrold子组件:

image.png
在父组件调用子组件,通过class传递了一个属性:

image.png
这是子组件的div上就会有两个class,一个是自身的hello,另一个是父组件透传过来的aa:

image.png
总结:如果一个子组件的根元素已经有了class或者style属性,他会和从父组件上继承的值进行合并。两种同时存在。

v-on监听器继承

同样的规则也适用于v-on事件监听器:

image.png
click监听器会被添加到MyButton的根元素,即那个原生的button元素之上,当原生的button点击时,会触发父组件的onclick方法,同样的,如果原生button元素自身也通过v-on绑定了一个事件监听器,则这个监听器和从父组件继承的监听器都会被触发。

深层组件继承

有些情况下一个组件会在根节点上渲染另一个组件,例如,我们重构一下MyButton,让她在根节点上渲染BaseButton(更深层的另一个组件,MyButton的子组件):

image.png
此时MyButton接收的透传属性会直接继续传给它的子组件BaseButton。
注意

  • 透传的属性不会包含MyButton上声明过的props或是针对emits声明事件的v-on侦听函数,换句话说,声明过的props和侦听函数被MyButton消费了。
  • 偷穿的属性若符合声明,也可作为props传给BaseButton。

禁用Attribute继承

在组件选项中设置inheritAttrs:false即可禁用。
最常见的需要禁用的场景就是属性不想应用在根元素上,而是其他的元素上。哪里需要继承就在哪里的模板表达式中直接使用$attrs访问。

image.png

image.png

image.png
注意

  • 和props有所不同,透传属性在js中保留了他们原始的大小写,所以向foo-bar这样的属性需要通过$attrs['foo-bar']来访问
  • 像@click这样的一个v-on事件监听器将在此对象下被暴露为一个函数$attrs.onclick。

多根节点的Attribute继承

和单根节点组件有所不同,有着多个根节点的组件没有自动attribute透传行为,如果$attrs没有显示绑定,将会帮厨一个运行时警告

image.png
如果$attrs被显示绑定,则不会有警告

image.png

在js中访问透传Attributes

如果需要,可以通过$attrs这个实例属性来访问组建的所有透传attribute。

image.png
注意:vue2里无法控制class和style的根元素继承,也就是inheritAttrs是不生效的