Nika Kurashvili
Nika Kurashvili

Reputation: 6474

What are inheritAttrs: false and $attrs used for in Vue?

As the question suggests, I can't figure out their meaning and why I should use it. It's said that it can be used so that when we have many components and we want to pass data from parent to the child's child's child's component, we don't have to use props. Is this true?

It'd be nice If you could provide an easier example. Vue.js docs don't mention much on it.

Upvotes: 55

Views: 57647

Answers (2)

canbax
canbax

Reputation: 3856

For me talking about $attrs and inheritAttrs together, makes it harder to understand. So I will show a bit more observations.

I will call my base-inp from HTML like below

<base-inp label="Username:" v-model="username" 
required placeholder="Enter your username"></base-inp>

The HTML for base-inp is like below

<label>
    {{ label }}
    <input v-bind="$attrs" :value="value" @input="$emit('input', $event.target.value)" />
</label>

v-bind="$attrs" is used to bind attributes.

If you set v-bind="$attrs" and inheritAttrs: true (default) and render your base-inp component. It will render enter image description here

So basically we are passing the attributes entered into base-inp component in the HTML template. And also into 'input' inside the base-inp. You can see 'placeholder' in both 'label' and 'input'.

If we delete v-bind="$attrs", the placeholder won't be an attribute in inner 'input' enter image description here

If you set v-bind="$attrs" and inheritAttrs: false, you will see attributes are not on the root element (label) but on inner input. enter image description here

Upvotes: 8

bernie
bernie

Reputation: 10400

Have a look at the "Disabling Attribute Inheritance" section of the docs and the api description for the full details.

It's main usage is to define so-called "transparent" components that pass-through attributes. The example given in the doc is a component wrapping an input element:

// Component
Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on:input="$emit('input', $event.target.value)"
      >
    </label>
  `
})

// Usage
<base-input
  v-model="username"
  required
  placeholder="Enter your username"
/>

The required and placeholder attributes are then set on the input instead of the wrapping label.

It doesn't really have anything to do with children of children of components but it can be used in such a hierarchy.

I hope that clears things up for you.

Upvotes: 55

Related Questions