loading

Vue Fallthrough Attributes

When attributes that aren’t declared as props are called on a component, they just fall through to the component’s root element.

Fallthrough attributes simplify our code because we don’t need to define the property as a prop, and they provide you with a better overview from the parent where the component is built.

The characteristics of class, style, and v-on are often utilized to fail.

Fallthrough Attributes

For example, it can be convenient to have the parent control component styling instead of the styling being tucked away inside the component.

Let’s build a new example in Vue, a simple to-do list, and see how the style attribute gets applied to the components that represent the tasks.

Therefore, the list of tasks, a <input> element, and a <button> for adding new tasks should all be present in our App.vue file. A <todo-item /> component is each item on the list.

App.vue:

				
					<template>
  <h3>Todo List</h3>  
  <ul>
    <todo-item
      v-for="x in items"
      :key="x"
      :item-name="x"
    />
  </ul>
  <input v-model="newItem">
  <button @click="addItem">Add</button>
</template>

<script>
  export default {
    data() {
      return {
        newItem: '',
        items: ['Buy apples','Make pizza','Mow the lawn']
      };
    },
    methods: {
      addItem() {
        this.items.push(this.newItem),
        this.newItem = '';
      }
    }
  }
</script>
				
			

And TodoItem.vue just gets the following instructions as a prop:

TodoItem.vue:

				
					<template>
  <li>{{ itemName }}</li>
</template>

<script>
  export default {
    props: ['itemName']
  }
</script>
				
			

The proper configuration of main.js is also necessary for our application to build correctly:

main.js:

				
					import { createApp } from 'vue'
  
import App from './App.vue'
import TodoItem from './components/TodoItem.vue'

const app = createApp(App)
app.component('todo-item', TodoItem)
app.mount('#app')
				
			

To show the point of this section, that properties can fall through to the root element inside the <template> of our component, we can give the list items some styling from App.vue:

Example

The <li> components within the component receive styling from App.vue:

				
					<template>
  <h3>Todo List</h3>
  <ul>
    <todo-item
      v-for="x in items"
      :key="x"
      :item-name="x"
      style="background-color: lightgreen;"
    />
  </ul>
  <input v-model="newItem">
  <button @click="addItem">Add</button>
</template>
				
			

We can right-click a <li> element in our to-do list in the browser and select ‘Inspect’ to verify that the style attribute has truly fallen through. As a result, we can see the style attribute is now on the <li> element:

Vue Fallthrough Attributes -

Merging 'class' and 'style' Attributes

The attributes will merge if “class” or “style” are already set and “class” or “style” attributes also originate from the parent as fallthrough attributes.

Example

We add a margin to the <li> components inside the TodoItem.vue component in addition to the styling that already exists from the parent:

				
					<template>
  <li style="margin: 5px 0;">{{ itemName }}</li>
</template>

<script>
  export default {
    props: ['itemName']
  }
</script>
				
			

An <li> element in the browser can be right-clicked to reveal that its characteristics have been combined. The component’s <li> element has a margin that is directly placed on it and combined with the background color that leaks from the parent:

Vue Fallthrough Attributes -

$attrs

It is no longer obvious which element the attributes should fall through to if the component has many elements at the root level.

We can use the built-in $attrs object to mark the element in order to specify which root element receives the fallthrough attributes. For example:

Example

TodoItem.vue:

				
					<template>
  <div class="pinkBall"></div>
  <li v-bind="$attrs">{{ itemName }}</li>
  <div class="pinkBall"></div>
</template>
				
			
Share this Doc

Vue Fallthrough Attributes

Or copy link

Explore Topic