Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue JS Non prop attributes and Disabling Attribute Inheritance

I have read the docs more than 5 times and I still can't understand what is Disabling Attribute Inheritance is used for and I don't understand the example given.

I understand how props works, it is passing data from parent component to child component.

Parent.vue

<template>
  <div id="app">
    <Child :num="num"></Child>
  </div>
</template>

<script>
import Child from "@/components/Child";
export default {
  name: "App",
  components: {
   Child
  },
  data() {
    return {
      num: 42
    };
  }
};
</script>

Child.vue

<template>
  <div>
    <h2>Child</h2>
    <h4>num is {{num}}</h4>
    <div id="total">
      <h4>total is {{total}}</h4>
    </div>
  </div>
</template>
<script>
export default {
  name: "Child",
  props: {
    num: {
      type: Number,
      default: 100
    }
  },
  data() {
    return {

    };
  },
  computed: {
    total() {
      return this.num + 20;
    }
  }
};
</script>

This will output num is 42 and total is 62. Which I understand perfectly.

However when it comes to Disabling Attribute Inheritance section , by base component, I assume they are referring to the child components.

"This pattern allows you to use base components more like raw HTML elements, without having to care about which element is actually at its root:"

What does this even mean ? Does this mean that parent don't have to pass on props anymore to the child and the child can automatically pick up the props from it's parent which frankly doesn't make sense or there is no parent component altogether, they are only using child component?

From their example, props: ['label' , 'value'] , how is the child component receiving these two props without the parent component passing these props to them?

I would be very thankful if someone can use the parent and vue component analogy above to provide a simple example of what does this even mean.

Thank you.

like image 209
desh Avatar asked Apr 30 '20 03:04

desh


2 Answers

Disabling Attribute Inheritance is used when you don't want html attributes assigned to the component to be passed to the root element in a component.

Parent.vue

<template>
  <div id="app">
    <Child title="I am the child"></Child>
  </div>
</template>

<script>
import Child from "@/components/Child";
export default {
  name: "App",
  components: {
   Child
  }
};
</script>

Child.vue

<template>
  <div>
    <h2 v-bind="$attrs">Child</h2> <!-- This h2 will inherit all the html attributes -->
  </div>
</template>
<script>
export default {
  inheritAttrs: false, // This is what disables attribute inheritance
  name: "Child"
};
</script>

inheritAttrs: false prevents the root component div from inheriting the title assigned to the Child component in Parent.vue.

Now notice how I use v-bind="$attrs" on the h2 in Child.vue. $attrs contains all the attributes that would have been assigned to the root div element. Now the attributes are assigned to the h2 and not the div.

inheritAttrs: false doesn't affect props or vue attributes, it affects normal html attributes. (It also doesn't affect style and class attributes)

Base Components

By "Base Components" the docs at vuejs.org means components like buttons, inputs, etc.

Using inheritAttrs: false is really useful for input components:

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

<script>
export default {
  name: 'base-input',
  inheritAttrs: false,
  props: ['label', 'value'],
}
</script>

This allows you to do:

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

Which means that the placeholder and required attributes are applied to the input in the component and not the label.

like image 104
DrevanTonder Avatar answered Oct 22 '22 13:10

DrevanTonder


If you put a random html attribute onto the component, it will appear on the rendered component. If you disable inheritance, it won't.

<my-component dorkus="whatever"></my-component>

when rendered, perhaps expands to

<div dorkus="whatever"> ... stuff ... </div>

but if you set inheritAttrs: false, it looks like

<div> ... stuff ... </div>

that's all there is to it.

dorkus="whatever" is still stored in the $attrs object, should we want to do something else with it.

like image 27
StayCool Avatar answered Oct 22 '22 15:10

StayCool