Vue-loader: Determining a Component Name

Created on 8 Sep 2016  路  6Comments  路  Source: vuejs/vue-loader

After reviewing the documentation
here: http://vue-loader.vuejs.org/en/index.html
and here: https://vue-loader.vuejs.org/en/start/spec.html

And after installing vue-cli and watching it work I still do not understand what determines the name of component.

It seems like this is a place were being explicit is warranted as I find myself confused.

Lets say I have a component file named Hello.vue containing:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  data () {
    return {   
      msg: 'Hello World!'
    }
  }
}
</script>

and a file App.vue that imports Hello.vue:

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

<script>
  import Hello from './components/Hello'

  export default {
    components: {
      Hello
    }
  }
</script>

I see that the component Hello is being imported by App.vue, and declared as a component. However, inside the template for App.vue I see a component element . This is all in lower case. I found that I can change this to and it still seems to work.

Inside of Hello.vue there is the wrapper <div class="hello">. I thought maybe this class name was related so I deleted class="hello", but it still ran fine. I was thinking that somehow I needed that class to bind to the component.

This brought me back to the line import Hello from './components/Hello' in App.vue.

The import Hello seems very strange given that nothing inside of Hello.vue is named Hello. Seems very implicit to me.

So is the file name identical to the component name? I've read lots of documentation, but haven't found the answer.

How could I explicitly declare the component name? I'm used to setting el, but I've never seen this option used in the docs.

Most helpful comment

If you declare a components name using the name option, e.g. export default { name: 'hello' }, that will always be the name used.

Otherwise, it will get the name used in local registration, e.g. components: { hello: Hello } will give it the name hello.

All 6 comments

If you declare a components name using the name option, e.g. export default { name: 'hello' }, that will always be the name used.

Otherwise, it will get the name used in local registration, e.g. components: { hello: Hello } will give it the name hello.

thanks

I've discovered that if I try to use dashes during component registration it breaks the babel-loader. When I remove the dash the error goes away. Template: webpack-simple-2.0

vcomponent: VComponent is fine.

v-component: VComponent breaks.

'v-component': VComponent works.

./~/babel-loader!./~/vue-loader/lib/selector.js?type=script&index=0!./src/App.vue
Module build failed: SyntaxError: C:/Users/asntoeh/PycharmProjects/vue-2-webpack-cli-test/src/App.vue: Unexpected token (14:15)

  12 | export default {
  13 |   components () {
> 14 |     'v-component': VComponent
     |                  ^
  15 |   },
  16 |   data () {
  17 |     return {

I fixed this by changing components () {...} to components: {...}. I'm very new to ES6.

@nueverest

In app.vue you are doing a local registration as it's called in the Vue Guide.

In this registration, you name the custom component as it is used in the template.

The error you refer to is not ES6, it is simply that an unquoted property name in a Javascript object can not use dashes. As an example you'll find many DOM properties have camelCase equivalents for convenience:

document.body.style['background-color'] = 'red'

... can more easily be written as:

document.body.style.backgroundColor = 'red'

... Which brings me to the interesting point here. In my tests (Vue 2.1.8), Vue actually checks for the kebab-case equivalent of the components you name. Hence if you declare a component with CamelCase like so:

components: {
  FooBarNav: FooBarNav   // <-- name of an imported .vue file
}

You can use it in the template like so

<foo-bar-nav></foo-bar-nav>

Better yet, you can use an ES6 shorthand, when the property name is the same as the value:

components: {
  // same as FooBarNav: FooBarNav
  FooBarNav
}

So in the last example it's pretty convenient that Vue translates CamelCase to kebab-case. Although you can use CamelCase component name in the .vue template and also in html page when using <script type="text/x-template"> (docs) I still prefer to stick to the html like syntax for consistency in my templates.

(Google brought me here while looking for another issue :))

image

image

Astonishing webpack build will compile the name to a single letter, and I don't know why. I'm using vue-cli webpack to init the project.

Was this page helpful?
0 / 5 - 0 ratings