Vue3:透传 Attributes

        "Transparent attribute" refers to an   attribute or   event listener that is passed to a component but is not declared as props  or  emits by the component. v-onThe most common examples are  class, style and id

   When a component is rendered with a single element as the root, the transparent attribute will be automatically added to the root element. For example, if we have a  <MyButton> component whose template looks like this:

<button>click me</button>

A parent component uses this component and passes in  class:

 <MyButton class="large" />

The final rendered DOM result is:

<button class="large">click me</button> 

Here, <MyButton> it is not  class declared as a prop that it accepts, so  class it is regarded as a transparent attribute, which is automatically transparently transmitted  <MyButton> to the root element

Merger   of class pairs and style

If a child component's root element already has an  class or  style attribute, it will be merged with the value inherited from the parent component. If we change the template of the previous  <MyButton> component to this:

<!-- <MyButton> 的模板 -->
<button class="btn">click me</button>

Then the final rendered DOM result will become:

<button class="btn large">click me</button> 

v-on listener inheritance 

The same rules apply to  v-on event listeners:

<MyButton @click="onClick" />

click The listener will be added to  <MyButton> the root element, the native  <button> element. When the native  <button> is clicked,  onClick the method of the parent component will be triggered. Similarly, if the native  button element itself is  v-on bound to an event listener, both the listener and the listener inherited from the parent component will be triggered.

deep component inheritance 

There are cases where a component renders another component on the root node. For example, let's refactor  <MyButton>it to render on the root node  <BaseButton>:

<!-- Template for <MyButton/>, just render another component -->
<BaseButton />

At this time,  <MyButton> the received transparent attribute will be passed on directly  <BaseButton>.

Please note:

  1. The transparently transmitted attribute will not contain  <MyButton> the declared props or the listener function for  emits the declaration event  v-on . In other words, the declared props and listener function are  <MyButton>"consumed".

  2. If the transparent attribute conforms to the declaration, it can also be passed in as props  <BaseButton>.

Disable Attributes inheritance

If you don't want a component to automatically inherit the attribute, you can set it in the component options  inheritAttrs: false.

If you use it  <script setup>, you need an extra  <script> block to write the option declaration:

<script>
// Use normal <script> to declare options
export default {   inheritAttrs: false } </script>


<script setup>
// ...setup part logic
</script>
 

The most common scenario where you need to disable attribute inheritance is when the attribute needs to be applied to elements other than the root node. By setting  inheritAttrs the option to  false, you can fully control how the transparently passed attribute is used.

These transparent attributes can be  $attrs accessed directly in template expressions.

<span>Fallthrough attribute: { { $attrs }}</span>

This  $attrs object contains   all other attributes except those declared by the component, such as  props ,  listeners  , etc.emitsclassstylev-on

There are a few points to note:

  • Unlike props, passthrough attributes retain their original case in JavaScript, so  foo-bar an attribute like this needs to  $attrs['foo-bar'] be accessed via .

  •  An event listener  like  @click this  will be exposed as a function under this object .v-on$attrs.onClick

Now we're going to use the component example from  the previous section<MyButton> again  . <button> Sometimes we may need to wrap a layer outside the element  for style  <div>:

<div class="btn-wrapper">
  <button class="btn">click me</button>
</div>

We want all  passthrough attributes like class and  v-on listeners to be applied on the inner ones  <button> and not  <div> on the outer ones. We can   do this  by setting inheritAttrs: false and using v-bind="$attrs"

<div class="btn-wrapper">
  <button class="btn" v-bind="$attrs">click me</button>
</div>

Tip: v-bind without parameters  will apply all attributes of an object to the target element as attributes. 

 

 

 

 

Guess you like

Origin blog.csdn.net/weixin_62364503/article/details/127192519