1
votes

I am trying to build a VueJS component. I have two other components which I want to use in a parent child manner. Now, I want to pass parent's data to child. It is like this:

App.vue

<template>
    <div id="app">
        <parent>
            <child></child>
            <child></child>
            <child></child>
            <child></child> 
        </parent>
    </div>
</template>

<script>
    import child from './child.vue'
    import parent from './parent.vue'

    var vm = new Vue({
      el: '#app',
      components: {
        parent,
        child
      }
    })  
</script>

parent.vue

<template>
    <div class="container">
        This is parent component
        <slot>
        </slot>
    </div>
</template>

<script>
    export default {
        name: 'parent',
        data () {
            return {
                parentMsg: {
                    'key1': 'value1',
                    'key2': 'value2'
                }
            }
        }
    }
</script>

child.vue

<template>
    <div class="container">
      Child component
      <!-- I have to place a div here which will consume parentMsg object -->
      <!-- Each instance of child component rendered should have access to parentMsg -->
      <div>
         <!-- Some HTML to consume the parentMsg -->  
      </div>
    </div>
</template>

<script type="text/javascript">
    export default {
        name: 'child',
        data () {
            return {
                demo: 'Demo message changed'
            }
        }
    }
</script>

I want parentMsg from parent.vue to be accessible in child.vue. I don't want to expose parentMsg on App.vue. How can I do this? I placed the div consuming parentMsg inside (and after too) unnamed slot in parent.vue template and thought that with each instance of child.vue, a copy of div will be rendered. It does not work.

2
Why dont you put the child-component in the parent template and pass the msg from parent to them ? Slots are not intended to be used like this.Georgi Antonov

2 Answers

1
votes

Why dont you put the child-component in the parent template and pass the msg from parent to them ? Slots are not intended to be used like this.

App.vue

<template>
    <div id="app">
        <parent>
        </parent>
    </div>
</template>

<script>
    import parent from './parent.vue'

    var vm = new Vue({
      el: '#app',
      components: {
        parent,
        child
      }
    })  
</script>

Parent.vue

<template>
    <div class="container">
        This is parent component
        <child :msg="key1"></child>
        <child :msg="key1"></child>
    </div>
</template>

<script>
    import child from './child.vue'

    export default {
        name: 'parent',
        data () {
            return {
                parentMsg: {
                    'key1': 'value1',
                    'key2': 'value2'
                }
            }
        }
    }
</script>

Child.vue

<template>
    <div class="container">
      Child component
      <div>
         {{msg}}
      </div>
    </div>
</template>

<script type="text/javascript">
    export default {
        name: 'child',
        props: {
          msg: String
        },
        data () {
            return {
                demo: 'Demo message changed'
            }
        }
    }
</script>
3
votes

You can pass data in slot in parent.vue

<template>
    <div class="container">
        This is parent component
        <slot :parentMsg="parentMsg"></slot>
    </div>
</template>

In app.vue access parentMsg through scope and pass as props to child:

<template>
    <div id="app">
        <parent>
           <template scope="defaultSlotScope">
            <child :msg="defaultSlotScope.parentMsg"></child>
            <child :msg="defaultSlotScope.parentMsg"></child>
            <child :msg="defaultSlotScope.parentMsg"></child>
            <child :msg="defaultSlotScope.parentMsg"></child>
          </template>
        </parent>
    </div>
</template

>

In child.vue use msg as props:

<template>
    <div class="container">
      <div>
         {{msg}}  
      </div>
    </div>
</template>

<script type="text/javascript">
    export default {
        name: 'child',
        props:['msg'],
        data () {
            return {
                demo: 'Demo message changed'
            }
        }
    }
</script>