Paul Toone
Paul Toone

Reputation: 143

Unknown custom element using VUE

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.

Upvotes: 3

Views: 5925

Answers (2)

Bert
Bert

Reputation: 82469

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>

Upvotes: 2

Bill Criswell
Bill Criswell

Reputation: 32921

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.

Upvotes: 3

Related Questions