The inheritAttrs Option in Vue

Attributes on a Vue.js component "fall through" to the displayed element by default. The top-level <div> in the MyComponent.vue template will inherit the class="text-5xl font-semibold" property in the following example.

In this tutorial i will be using Tailwind CSS for my styling

//MyComponent.vue

<template>
  <div>
    <p>This is my Component</p>
  </div>
</template>

//app.vue

<template>
  <div>
    <MyComponent class="text-5xl font-semibold" />
  </div>
</template>

In other words, the rendered element would seem as follows.

<template>
  <div class="text-5xl font-semibold" >
    <p>This is my Component</p>
  </div>
</template>

inheritAttrs

Vue introduces an inheritAttrs utility only available in the options API to choose if this fall through behavior should be allowed or not. Setting inheritAttrs to false prevents this fall through behavior. In the following example, the <div> in MyComponent will not inherit the class attribute, or any other attribute.

//MyComponent.vue

<template>
  <div>
    <p>This is my Component</p>
  </div>
</template>

<script>
export default {
  inheritAttrs: false,
}
</script>

In scenarios when you wish to construct an internal event handler that fires the user-specified event handler, inheritAttrs comes in handy. For example, inheritAttrs is used for our async-button component, which when clicked performs an async function and disables the button for the duration of the async function. In addition to running the user-specified @click handler, the async-button component must execute some logic to deactivate itself.

//async-button.vue

<script>
export default {
  inheritAttrs: false,
data () {
return {
        status: 'init'
        }
    }
methods: {
    // When the user clicks the button, we actually call
    // the `handleClick()` method first...
    async handleClick(ev) {
      if (this.status === 'in_progress') {
        return;
      }
      this.status = 'in_progress';
      try {
        // and the `handleClick()` method calls the user-specified
        // `@click` handler. `this.$attrs` refers to the attributes
        // specified on `<async-button>` in HTML.
        await this.$attrs.onClick(ev);
      } catch (err) {
        this.status = 'error';
        throw err;
      }
      this.status = 'success';
    }
  },
  computed: {
    // Use "selective binding". Bind all attributes _except_
    // `onClick` and `disabled`, because `async-button` wraps
    // those attributes. Styles and class names still fall through.
    attrsToBind() {
      const attrs = { ...this.$attrs };
      delete attrs.onClick;
      delete attrs.disabled;
      return attrs;
    },
    isDisabled() {
      return this.status === 'in_progress' || this.$attrs.disabled;
    }
  },
}
</script>

Below is the HTML for the async-buttoncomponent. Note that v-bind binds any additional attributes, other than disabled and onClick.

<button v-bind="attrsToBind" :disabled="isDisabled" @click="handleClick">
  <slot></slot>
</button>

Get more information on the inheritAttrs utility from the Vue.js Documentation page.