25

I have a very basic VueJS app which I'm building by following the website.

Here's the code, why is this component not rendering?

HTML:

    <script src="https://unpkg.com/vue"></script>
    
    <div id="app">
      <p>{{ message }}</p>
    </div>
    
    <div>
    <ol>
      <todo-item></todo-item>
    </ol>
    </div>

JS:

    new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue.js!'
      }
    })
    
    Vue.component('todo-item', {
        template: '<li>This is a list item</li>'
    })
2
  • 4
    Your <todo-item> is outside of <div id="app">, which is the Vue mount point. Commented Jun 28, 2017 at 14:39
  • @yuriy636 doesn't work even if I put my <ol> inside div#app .. link Commented Jun 28, 2017 at 14:42

4 Answers 4

54
  • Use the component inside of the specified el mount element
  • Define the component before initializing the Vue instance with new Vue

Vue.component('todo-item', {
  template: '<li>This is a list item</li>'
})

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <ol>
    <todo-item></todo-item>
  </ol>
  <p>{{ message }}</p>
</div>

<div>

</div>

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

4 Comments

This one is the correct answer. And according to the doc, it's indeed required to declare component BEFORE instantiating Vue :)
You should really take a look at the single file component structure instead of defining every component in one file if you want a to enlarge your application.
I just became aware of the fact that I obviously down-voted this answer quite some time ago. I have no idea why and assume that I clicked by mistake. However, meanwhile I cannot undo it, my choice is "locked", unless the answer will be edited. So I ask the yuriy636 to edit something in her/his answer so I can undo my stupid downvote. I am really sorry for that!
Glad you got the message and could edit your answer, @yuriy636! I could turn-around my vote into an up-vote! Thanks for your understanding!
14

Better, you can use the Single File Components to define the todo-item component inside another file:

app.vue

 import TodoItem from './components/todo-item'

 new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  },
  components: {
    TodoItem
  }
})

components/todo-item.vue

<template>
  <li>This is a list item</li>
</template>

<script>
  export default {
    name: 'todo-item'
  }
</script>

In many Vue projects, global components will be defined using Vue.component, followed by new Vue({ el: '#container' }) to target a container element in the body of every page.

This can work very well for small to medium-sized projects, where JavaScript is only used to enhance certain views. In more complex projects however, or when your frontend is entirely driven by JavaScript, these disadvantages become apparent:

  • Global definitions force unique names for every component
  • String templates lack syntax highlighting and require ugly slashes for multiline HTML
  • No CSS support means that while HTML and JavaScript are modularized into components, CSS is conspicuously left out
  • No build step restricts us to HTML and ES5 JavaScript, rather than preprocessors like Pug (formerly Jade) and Babel

All of these are solved by single-file components with a .vue extension, made possible with build tools such as Webpack or Browserify.

3 Comments

That doesn't work in the Fiddle for me on Chrome. Do you think the Fiddle just loads Vue incorrectly?
I've added some explanations
Vue.Component('...') will declare the component globally. It's wrong to use Vue.Component inside components {}
4

My components was also not rendering.

In case it's not that obvious, like it was to me, take a look at how you are importing components.

For example, first I had:

import { CurrencyConverter } from "./CurrencyConverter.vue";

And had to remove the brackets, so it looked like this:

import CurrencyConverter from "./CurrencyConverter.vue";

Ofcourse, this means in your component you use the syntax:

export default {
    name: "CurrencyConverter",
}

Comments

1

I just have similar problem. After I try what @yuriy636 said it still not rendering. And I found that there is a component declaration in componets field like this:

Vue.component('todo-item', {
    template: '<li>This is a list item</li>',
})

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  },
  components: {
    'todo-item': 'todo-item',  <--- see this ?
  }
})

After I remove 'todo-item': 'todo-item'. It works!

Hope this help other guys!

Comments

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.