New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursive components problem: Vue.component() does not respect "name" prop defined in options #3039

Closed
jiangfengming opened this Issue Jun 6, 2016 · 16 comments

Comments

Projects
None yet
10 participants
@jiangfengming

jiangfengming commented Jun 6, 2016

JSFiddle: http://jsfiddle.net/fenivana/wso9prne/

Vue.js version: latest

tree.js:

module.exports = {
    name: 'v-tree',
  props: ['list'],
  template: '<ul>' +
              '<li v-for="item in list">{{item.value}}' + 
                '<v-tree v-if="item.children" :list="item.children"></v-tree>' + 
              '</li>' +
            '</ul>'
};

app.js:

var tree = require('./tree');

// registered the tree component with a different name
// e.g. add namespace
// this will cause error
Vue.component('ns-tree', tree);

// but if I registered it with
// Vue.component('ns-tree', Vue.extend(tree));
// this works fine.

new Vue({
    el: 'body',
    data: {
        list: [
        { value: 'foo' },
        { value: 'bar', children: [
          { value: 'baz' }
        ] }
      ]
    }
});

app.html:

<ns-tree :list="list"><</ns-tree>

Throws error:

VM408 vue.js:1018 [Vue warn]: Unknown custom element: <v-tree> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

Using Vue.component('ns-tree', Vue.extend(tree)) works fine, but this is verbose, and I need to tell the users of this component that you need to call Vue.extend() before Vue.component(), or you must register as the same name as the internal name.

@jiangfengming jiangfengming changed the title from Recursive components problem: Registered component as global does not respect "name" prop defined in options to Recursive components problem: Vue.component() does not respect "name" prop defined in options Jun 7, 2016

@kazupon

This comment has been minimized.

Show comment
Hide comment
@kazupon

kazupon Jun 7, 2016

Member

Hi!
Thank you for your reporting!

You can use the name options at only Vue.extend().
Please see the below document.
http://vuejs.org/api/#name

I think that you can resolve with a way the below jsfiddle URL.
http://jsfiddle.net/kazupon/7u1xpaoh/1/

Member

kazupon commented Jun 7, 2016

Hi!
Thank you for your reporting!

You can use the name options at only Vue.extend().
Please see the below document.
http://vuejs.org/api/#name

I think that you can resolve with a way the below jsfiddle URL.
http://jsfiddle.net/kazupon/7u1xpaoh/1/

@kazupon kazupon closed this Jun 7, 2016

@yyx990803

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 Jun 7, 2016

Member

I think this is something that can be fixed since the expected behavior is reasonable.

Member

yyx990803 commented Jun 7, 2016

I think this is something that can be fixed since the expected behavior is reasonable.

@yyx990803 yyx990803 reopened this Jun 7, 2016

@kazupon

This comment has been minimized.

Show comment
Hide comment
@kazupon

kazupon Jun 7, 2016

Member

@yyx990803
So that means, if we specified component included name option to Vue.components(), Should we register the component, not global id but name option?

Member

kazupon commented Jun 7, 2016

@yyx990803
So that means, if we specified component included name option to Vue.components(), Should we register the component, not global id but name option?

@jiangfengming

This comment has been minimized.

Show comment
Hide comment
@jiangfengming

jiangfengming Jun 7, 2016

@kazupon The component is published on npm and github, the author doesn't know what name the users will use.

Vue.component('id', {
  name: 'internal-name',
 ...
})

id is for outside use, name is for internal use.

I think we can check whether name is defined at global-api.js:213

if (!definition.name) {
  definition.name = id
}

jiangfengming commented Jun 7, 2016

@kazupon The component is published on npm and github, the author doesn't know what name the users will use.

Vue.component('id', {
  name: 'internal-name',
 ...
})

id is for outside use, name is for internal use.

I think we can check whether name is defined at global-api.js:213

if (!definition.name) {
  definition.name = id
}
@kazupon

This comment has been minimized.

Show comment
Hide comment
@kazupon

kazupon Jun 7, 2016

Member

@fenivana
Thanks for your explanation!

Oh, I see.
I'll try to fix this issue.

Member

kazupon commented Jun 7, 2016

@fenivana
Thanks for your explanation!

Oh, I see.
I'll try to fix this issue.

@kazupon kazupon added the improvement label Jun 7, 2016

@kazupon kazupon self-assigned this Jun 7, 2016

kazupon added a commit to kazupon/vue that referenced this issue Jun 7, 2016

@jiangfengming

This comment has been minimized.

Show comment
Hide comment
@jiangfengming

jiangfengming Jun 7, 2016

@kazupon Thanks! I really like the quick response of Vuejs Team, you're awesome!

jiangfengming commented Jun 7, 2016

@kazupon Thanks! I really like the quick response of Vuejs Team, you're awesome!

yyx990803 added a commit that referenced this issue Jun 8, 2016

@yyx990803

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 Jun 8, 2016

Member

Closed via #3040

Member

yyx990803 commented Jun 8, 2016

Closed via #3040

@yyx990803 yyx990803 closed this Jun 8, 2016

@peshkov3

This comment has been minimized.

Show comment
Hide comment
@peshkov3

peshkov3 Oct 7, 2016

@kazupon
Thank you for your work! VueJS is awesome.
Could you please correct the official example? (It does not contain 'name' attribute in Vue.component definition)
https://vuejs.org/examples/tree-view.html

peshkov3 commented Oct 7, 2016

@kazupon
Thank you for your work! VueJS is awesome.
Could you please correct the official example? (It does not contain 'name' attribute in Vue.component definition)
https://vuejs.org/examples/tree-view.html

@fingerpich

This comment has been minimized.

Show comment
Hide comment
@fingerpich

fingerpich Jul 5, 2017

How do i set different name and id in .vue file?

fingerpich commented Jul 5, 2017

How do i set different name and id in .vue file?

@EmadAdly

This comment has been minimized.

Show comment
Hide comment
@EmadAdly

EmadAdly Aug 6, 2017

@fingerpich

<script>
export default {
  name: 'is-name',
...
</script>

EmadAdly commented Aug 6, 2017

@fingerpich

<script>
export default {
  name: 'is-name',
...
</script>
@fingerpich

This comment has been minimized.

Show comment
Hide comment
@fingerpich

fingerpich Aug 6, 2017

@EmadAdly I want to have different name and id in .vue file because I have used a component recursively.
how do you set the id (global name)?

fingerpich commented Aug 6, 2017

@EmadAdly I want to have different name and id in .vue file because I have used a component recursively.
how do you set the id (global name)?

@appurist

This comment has been minimized.

Show comment
Hide comment
@appurist

appurist Aug 26, 2017

@fingerpich I'm still working on some of these concepts myself, but I think you'd do the following to set the component name globally... In the same file where you create the Vue instance (i.e. where new Vue(...) is), above/before that Vue instance creation, add something like:

import MyComponent from '@/components/MyComponent.vue';
Vue.component('my-component',MyComponent)

new Vue(...) {

Defining them in the components: member in the app or another component makes them only available to the template used there.

appurist commented Aug 26, 2017

@fingerpich I'm still working on some of these concepts myself, but I think you'd do the following to set the component name globally... In the same file where you create the Vue instance (i.e. where new Vue(...) is), above/before that Vue instance creation, add something like:

import MyComponent from '@/components/MyComponent.vue';
Vue.component('my-component',MyComponent)

new Vue(...) {

Defining them in the components: member in the app or another component makes them only available to the template used there.

@appurist

This comment has been minimized.

Show comment
Hide comment
@appurist

appurist Aug 26, 2017

BTW, I found this issue because I was getting the did you register the component correctly? error as well. It seems the name member of a single-file .vue component is ignored. I've stopped including the names there, and started naming them in the components: member where they are referenced (or globally as above), e.g.:

import MyComponent from '@/components/MyComponent.vue';
export default {
  components: {
    'my-component': MyComponent
  }

That will only be valid there, but the other approach above can be used for global registrations.

It seems more appropriate to me to only register them where they are used (locally), however I'm not sure of the performance impact of registering them locally repeatedly, if it's a component nested within many components.

appurist commented Aug 26, 2017

BTW, I found this issue because I was getting the did you register the component correctly? error as well. It seems the name member of a single-file .vue component is ignored. I've stopped including the names there, and started naming them in the components: member where they are referenced (or globally as above), e.g.:

import MyComponent from '@/components/MyComponent.vue';
export default {
  components: {
    'my-component': MyComponent
  }

That will only be valid there, but the other approach above can be used for global registrations.

It seems more appropriate to me to only register them where they are used (locally), however I'm not sure of the performance impact of registering them locally repeatedly, if it's a component nested within many components.

@lethak

This comment has been minimized.

Show comment
Hide comment
@lethak

lethak Nov 1, 2017

Indeed, name in single-file .vue component seems ignored.

I am running into this right now

lethak commented Nov 1, 2017

Indeed, name in single-file .vue component seems ignored.

I am running into this right now

@YellowPanda11

This comment has been minimized.

Show comment
Hide comment
@YellowPanda11

YellowPanda11 Dec 18, 2017

Dynamically importing the single-file component solved the issue for me.

YellowPanda11 commented Dec 18, 2017

Dynamically importing the single-file component solved the issue for me.

@KimAbliter

This comment has been minimized.

Show comment
Hide comment
@KimAbliter

KimAbliter Apr 2, 2018

I also have same issue, it displays "Unknown custom element: < random-quote > - did you register the component correctly? For recursive components, make sure to provide the "name" option."
This is the library I use: https://github.com/laravue/laravue
here is my code:

  • app.js
var Vue = require('vue')
Vue.config.debug = true // Comment this line for production

new Vue({
    el: '#app',
    created: function() {
        this.laravue.init.call(this, ['home']);
    },
    data: {
        laravue: require('./laravue.coffee')
    },
    components: require('./components.coffee') 
})
  • components.coffee
    # Custom Elements
    'titles': require './components/title.coffee'
    'random-quote': require './components/random-quote.coffee'

    # Views
    'home-view': require './views/home.coffee'
  • random-quote.coffee
module.exports =
    template: require './random-quote.template.html'
    created: () ->
        random = Math.floor(Math.random() * 6)
        @quote = @quotes[random]

    data: () ->
        ret =
            quote: ''
            quotes: [
                "Notice the small things. The rewards are inversely proportional."
                "Even the largest avalanche is triggered by small things."
                "Great things are done by a series of small things brought together."
                "Great things are not done by impulse, but by a series of small things brought together."
                "Coming together is a beginning; keeping together is progress; working together is success."
                "From small beginnings come great things."
            ]
  • random-quote.template.html
<div class="quote">{{quote}}</div> 

KimAbliter commented Apr 2, 2018

I also have same issue, it displays "Unknown custom element: < random-quote > - did you register the component correctly? For recursive components, make sure to provide the "name" option."
This is the library I use: https://github.com/laravue/laravue
here is my code:

  • app.js
var Vue = require('vue')
Vue.config.debug = true // Comment this line for production

new Vue({
    el: '#app',
    created: function() {
        this.laravue.init.call(this, ['home']);
    },
    data: {
        laravue: require('./laravue.coffee')
    },
    components: require('./components.coffee') 
})
  • components.coffee
    # Custom Elements
    'titles': require './components/title.coffee'
    'random-quote': require './components/random-quote.coffee'

    # Views
    'home-view': require './views/home.coffee'
  • random-quote.coffee
module.exports =
    template: require './random-quote.template.html'
    created: () ->
        random = Math.floor(Math.random() * 6)
        @quote = @quotes[random]

    data: () ->
        ret =
            quote: ''
            quotes: [
                "Notice the small things. The rewards are inversely proportional."
                "Even the largest avalanche is triggered by small things."
                "Great things are done by a series of small things brought together."
                "Great things are not done by impulse, but by a series of small things brought together."
                "Coming together is a beginning; keeping together is progress; working together is success."
                "From small beginnings come great things."
            ]
  • random-quote.template.html
<div class="quote">{{quote}}</div> 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment