16
votes

I am quite new to VueJS. In react you can easily use rest params for passing props to children. Is there a similar pattern in Vue?

Consider this parent component that has a few children components:

<template>
<header class="primary-nav">
<search-bar :config="searchBar"><search-bar>
//          ^^^^ this becomes the key on the props for SearchBar
header>
</template>

export default {
  data(){
    return {
      ... a few components ...
      searchBar : {
        model: '',
        name: 'search-bar',
        placeholder: 'Search Away',
        required:true,
        another: true
        andanother: true,
        andonemoreanotherone:true,
        thiscouldbehundredsofprops:true
      }
    }
  }
}

<template>
    <div :class="name">
        <form action="/s" method="post">
            <input type="checkbox">
            <label :for="config.name" class="icon-search">{{config.label}}</label>
            <text-input :config="computedTextInputProps"></text-input>
                        //^^^^ and so on. I don't like this config-dot property structure.
        </form>
    </div>
</template>

  export default {
    props: {
        name: String,
        required: Boolean,
        placeholder: String,
        model: String,
    },
    computed: {
     computedtextInputProps(){
       return justThePropsNeededForTheTextInput
     }
    }
 ...  

What I don't like is that the props are named-spaced with the key config, or any other arbitrary key. The text-input component ( not shown ) is a glorified input field that can take a number of attributes. I could flatten the props when the component is created, but is that generally a good idea?

I am surprised this question hasn't been asked before.

Thanks.

Edit: 10-06-2017

Related: https://github.com/vuejs/vue/issues/4962

3
You can pass an object as a prop, containing all needed key-value pairs. - Egor Stambakio
That's what I am I have illustrated here. The :config key is the prop key on the child. Which is not what I want. - Simon

3 Answers

33
votes

Parent component

<template>
  <div id="app">
    <child-component v-bind="propsToPass"></child-component>
  </div>
</template>

<script>
  import ChildComponent from './components/child-component/child-component'

  export default {
    name: 'app',
    components: {
      ChildComponent
    },
    data () {
      return {
        propsToPass: {
          name: 'John',
          last_name: 'Doe',
          age: '29',
        }
      }
    }
  }
</script>

Child Component

<template>
  <div>
    <p>I am {{name}} {{last_name}} and i am {{age}} old</p>
    <another-child v-bind="$props"></another-child> <!-- another child here and we pass all props -->
  </div>
</template>

<script>
  import AnotherChild from "../another-child/another-child";
  export default {
    components: {AnotherChild},
    props: ['name', 'last_name', 'age'],
  }
</script>

Another Child component inside the above component

<template>
    <h1>I am saying it again: I am {{name}} {{last_name}} and i am {{age}} old</h1>
</template>

<script>
    export default {
      props: ['name', 'last_name', 'age']
    }
</script>
9
votes

Parent component

You can pass as many props as you want to child component

enter image description here

Child Component

Once you are satisfied with all the props, then you can use v-bind="$props" inside your child component to retrieve all the props.

enter image description here

Final Result:

enter image description here

Done:)

2
votes

In vue 3, addition to attributes passing, events/listeners can be also passed to child components.

Parent component

<template>
    <div>
       <Button @click="onClick">Click here</Button>
    </div>
</template>

<script>
import Button from "./Button.vue";
export default {
    methods:{
        onClick(evt) {
            // handle click event here
        }
    }
}
</script>

Child component

Button.vue

<template>
    <button v-bind="$attrs" v-on="$listeners">
        <slot />
    </button>
</template>