3

I'm new to Vue and am having some trouble with a few things. First, off I was following this tutorial: eventbus. If I put all the code (html, JS and CSS) in one html file, this works just as described in this tutorial.

However, I have been reading and I was following a VUE cli app structure. I used vue init webpack vueapp01 So, I have an index.html file in the vueapp01 root folder, in the src folder I have an app.vue and two vue files in the components folder; the-box.vue and the-button.vue; along with all the other files loaded by the vue template webpack.

Instead of having all the code in one html file (which works) I have the code separated out like this: index.html:

<!DOCTYPE html>
<html>
 
<head>
    <meta charset="utf-8">
    <title>vueapp01</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script> 
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
App.vue:

<template>
<div id="the-example" class="container">
  <h1>Building an Event Bus with <a href="https://vuejs.org" target="_blank">Vue.js</a></h1>
  <div class="row">  
    <div class="col-xs-6">
      <the-button what="Event #1"></the-button>
      <the-button what="Event #2"></the-button>
      <the-button what="Event #3"></the-button>
    </div>
    <div class="col-xs-6">
      <the-box name="Receiver #1"></the-box>  
    </div>
  </div>
</div>
  </div>   
</template>

<script>
    import the-button from './components/the-button'
    import the-box from './components/the-box'

    export default {
      name: 'app',
      components: {
        the-button,the-box
      }
    }
</script>
<--
<script>
/******************************************
The Central Event Bus Instance
*******************************************/
let EventBus = new Vue();

</script>
the-box.vue:

/******************************************
Example Root Vue Instance
*******************************************/
new Vue({el: "#the-example"});

/******************************************
A sample Vue.js component that emits an event
*******************************************/

let TheButton = Vue.extend({
	name: "the-button",
  props: ["what"],
  template: `
  	<button class="btn btn-md btn-success the-button" @click="makeItHappen()">Sender: {{what}}</button>
  `,
  methods: {
  	makeItHappen: function(){
    	EventBus.$emit("somethingHappened", this.what)
    }
  }
});

Vue.component("the-button", TheButton);
the-button.vue:

/******************************************
A sample Vue.js component that received an event
*******************************************/

let TheBox = Vue.extend({
	name: "the-box",
  props: ["name"],
  template: `
  	<div class="well">
    	<div class="text-muted">{{name}}</div>	
    	<div>{{respondedText}}</div>
     </div>
  `,
  data: function(){
  	return {
    	respondedText: null
    }
  },
	created: function(){
  	EventBus.$on('somethingHappened', (what)=>{
    	this.respondedText = 'Event Received: ' + what;
    })
  	console.log("Responder")
  }

});

Vue.component("the-box", TheBox);

Currently, I'm getting the errors, "unknown custom element the-box", "unknown custom element the-button". I've tried switching the script and template orders to have templates load first but I still have no luck.

Any help would be greatly appreciated. Also, I assume I'm doing this correctly by separating these components out to separate files but if that is incorrect I'd gladly take criticism on the way I'm learning to use Vue.

4
  • 2
    import the-button from './components/the-button' is not valid javascript. I'm not sure how you are getting as far as you say you are. You can't have a dash in a variable. Commented Aug 30, 2017 at 17:56
  • @Bert I just changed them throughout the code to not include the dash and I still have the same errors popping up. Commented Aug 31, 2017 at 16:11
  • When you import a single file component, you typically have to specify the extension so that it will be run through vue-loader. So are you using import TheButton from './components/the-button.vue'? Note the extension. Commented Aug 31, 2017 at 16:15
  • @Bert, I made that change too and it still gave errors unknown custom element. Also, I'm including the jsfiddle example I'm working from: jsfiddle.net/arvidkahl/gxdn6ycv/… I just want to learn how to take a bus example that works when I put it all in the app.vue file and separate it out into an app.vue file while also importing components Commented Aug 31, 2017 at 16:22

2 Answers 2

3

Change:

import the-button from './components/the-button'
import the-box from './components/the-box'

to

import TheButton from './components/the-button'
import TheBox from './components/the-box'

and do

components: {
  TheButton,
  TheBox,
}

There must be another far larger error somewhere you're somehow not seeing.

Sign up to request clarification or add additional context in comments.

2 Comments

I made those changes and it still gives the same error. Is it alright that I have the Vue.component("the-box, TheBox) and Vue.component("the-button, TheButton) in the bottom of the vue files? Should those be in the app.vue?
I have not found any larger errors than this. I have the basic vue init webpack vue003 installed and that app works great, so I know VUE is functioning fine
2

Here is a full example of how the files should look to implement that fiddle in single file components assuming you used vue init webpack <project>.

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>bus</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

main.js

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

Vue.config.productionTip = false

window.EventBus = new Vue()

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})

App.vue

<template>
<div id="the-example" class="container">
  <h1>Building an Event Bus with <a href="https://vuejs.org" target="_blank">Vue.js</a></h1>
  <div class="row">  
    <div class="col-xs-6">
      <the-button what="Event #1"></the-button>
      <the-button what="Event #2"></the-button>
      <the-button what="Event #3"></the-button>
    </div>
    <div class="col-xs-6">
      <the-box name="Receiver #1"></the-box>  
      <the-box name="Receiver #2"></the-box>  
      <the-box name="Receiver #3"></the-box>  

    </div>
  </div>
</div>
</template>

<script>
    import TheButton from './components/TheButton.vue'
    import TheBox from './components/TheBox.vue'

    export default {
      name: 'app',
      components: {
        TheButton, TheBox
      }
    }
</script>

components/TheBox.vue

<template>
    <div class="well">
        <div class="text-muted">{{name}}</div>  
        <div>{{respondedText}}</div>
    </div>
</template>

<script>
export default {
    name: "the-box",
  props: ["name"],
  data: function(){
    return {
        respondedText: null
    }
  },
    created: function(){
    EventBus.$on('somethingHappened', (what)=>{
        this.respondedText = 'Event Received: ' + what;
    })
    console.log("Responder")
  }

}
</script>

components/TheButton.vue

<template>
    <button class="btn btn-md btn-success the-button" @click="makeItHappen()">Sender: {{what}}</button>
</template>

<script>
export default {
    name: "the-button",
  props: ["what"],
  methods: {
    makeItHappen: function(){
        EventBus.$emit("somethingHappened", this.what)
    }
  }

}
</script>

1 Comment

That did it! Thank you so much for all your help, I really appreciate it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.