Pass all props to children in Vue
Tags: vue, javascript, webdev
Published: 2019-08-16 17:15:25

---
title: Pass all props to children in Vue
published: true
description: Pass all component props down through layers of child components in VueJS
tags: vue, javascript, webdev
---

*This article is also posted on my [blog](https://jwkicklighter.com/posts/pass-all-props-to-children-in-vue).*

While brainstorming some new Vue components, I wanted to have a way that a single wrapper component could fetch all of the data needed for the children views, and pass that data through (around 5 layers of) children down to the the bottom.

So I did some experimenting, and here’s a way to pass all component props down through child components. [Link to codepen](https://codepen.io/jwkicklighter/pen/zYOBvmr).

Vue actually makes this very easy for us. All component props are available in the `$props` object (`this.$props` if you're not in the template), and we can use the Vue directive `v-bind` without specifying a specific prop name in order to bind a whole object of props to the child.

## Example

Let's assume we have some wrapper component that is going to render a child `comp1` component and pass it both `propForComp1` and `propForComp2` as props.

Here's `Comp1.vue`:

```vue
<template>
  <div class="comp1">
    <span>{{ propForComp1 }}</span>
    <comp2 v-bind="$props" />
  </div>
</template>

<script>
  export default {
    components: Comp2,
    props: [
      'propForComp1',
      'propForComp2'
    ],
  }
</script>
```

Notice that `comp1` is only using `propForComp1` and doesn't really care about `propForComp2`. But since it needs to be included in the props passed to `comp2`, `propForComp2` still needs to be declared inside the `props` object. If not, `$props` will not contain it.

You can do this for many levels of components, but remember that the props **any** child needs must be declared in **all** parents. So if you have 5 layers, `propForComp5` must be declared as a prop in `prop1`, `prop2`, `prop3`, `prop4`, and `prop5`. You can make this a little easier by using a Mixin, which is the route I took in the [codepen](https://codepen.io/jwkicklighter/pen/zYOBvmr).

**UPDATE**: You actually don't have to do this last bit! Just like Vue gives up `$props`, the `$attrs` object includes all of the passed attributes that the component **doesn't** declare as props. This means, that we can simply use `v-bind="$attrs"` to pass down the attributes that children would care about, even if the component doesn't specify them itself.

The previous example would turn into:

```vue
<template>
  <div class="comp1">
    <span>{{ propForComp1 }}</span>
    <comp2 v-bind="$props" v-bind="$attrs" />
  </div>
</template>

<script>
  export default {
    components: Comp2,
    props: [
      'propForComp1'
    ],
  }
</script>
```

A diff to see the changes:

```diff
<template>
  <div class="comp1">
    <span>{{ propForComp1 }}</span>
-   <comp2 v-bind="$props" />
+   <comp2 v-bind="$props" v-bind="$attrs" />
  </div>
</template>

<script>
  export default {
    components: Comp2,
    props: [
      'propForComp1',
-     'propForComp2'
    ],
  }
</script>
```

Thanks to @morficus for pointing this out!