8

I am trying to figure out how to make one component inside of another one in VueJS. For instance, something like this, which unfortunately does not work (the child component appears to do nothing):

http://www.webpackbin.com/NyI0PzaL-

I am equally interested in doing this using inline-templates as much as by using the .vue file extension method as shown above.

Here is the code from the non-working example above:

main.js

import Vue from 'vue'
import App from './App.vue'
import Child from './Child.vue'

new Vue({
  el: 'body',
  components: { App, Child }
})

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
  </head>
  <body>
    <app></app>
    <script src="main.js"></script>
  </body>
</html>

App.vue

<template>
  <div>
      <h1>{{ parent_msg }}</h1>
      <child></child>
  </div>
</template>

<script>
export default {
  data () {
    return {
      parent_msg: 'Hello From the Parent!'
    }
  }
}
</script>

Child.vue

<template>
  <h1>{{ child_msg }}</h1>
</template>

<script>
export default {
  data () {
    return {
      child_msg: 'Hello From the Child!'
    }
  }
}
</script>

Even though this above example is hosted on webpackbin.com, in the two projects where I would like to use this, I am using Laravel in one along with Laravel Spark in the other. In the plain Laravel app, I'm primarily using .vue files, and in the Laravel Spark app, I'm primarily using inline-templates. I'd be especially grateful for any working samples. Thanks!


UPDATE

Thanks to Linus for his answer below. It appears I need these changes to register the child component globally in my main.js file:

import Vue from 'vue'
import App from './App.vue'
import Child from './Child.vue'
Vue.component('child', Child);

new Vue({
  el: 'body',
  components: { App, Child }
})

Alternatively, in order to keep the child component local to be used within the parent, I could change the parent component (App.vue) as follows:

<template>
  <h1>{{ parent_msg }}</h1>
  <div>
      <child></child>
  </div>
</template>

<script>
import Child from './Child.vue';
export default {
  components: {Child},
  data () {
    return {
      parent_msg: 'Hello from the parent component!'
    }
  }
}
</script>
Bryan Miller
  • 3,262
  • 4
  • 27
  • 51
  • Your code is right. Are you running it through the vueify extension? Your webpackbin is not the same code here. – Jeff Jul 12 '16 at 00:06
  • 1
    Move your child import to the app.vue and add the component hash there for the child. – vbranden Jul 12 '16 at 05:34

1 Answers1

12

You registered the Child component locally in the main instance, so it is not available in App.vue

Remove it form the main instance and add it to App.vue:

App.vue

<template>
  <div>
      <h1>{{ parent_msg }}</h1>
      <child></child>
  </div>
</template>

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

export default {
  data () {
    return {
      parent_msg: 'Hello From the Parent!'
    }
  },
  components: {child: Child}
}
</script>

..or register it globally with Vue.component('child', Child) in your main.js file. Then it's available everywhere.

Linus Borg
  • 23,622
  • 7
  • 63
  • 50
  • thanks for your answer. I will test it out when I get a chance. – Bryan Miller Jul 12 '16 at 16:27
  • Your answer appears to be working, at least on WebpackBin. Hopefully I can get it to work in Laravel now, as well! – Bryan Miller Jul 13 '16 at 00:27
  • 1
    Great solution, could you tell me how to display 'parent_msg' to child component and vice versa ? – raju Nov 10 '16 at 15:51
  • https://stackoverflow.com/users/4527328/raju-shrestha - Check this out for communicating between nested components https://laracasts.com/discuss/channels/vue/difference-between-props-and-data – Artistan Jul 06 '17 at 17:31