vue: Recursive components problem: Vue.component() does not respect "name" prop defined in options
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.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 2
- Comments: 22 (5 by maintainers)
Commits related to this issue
- fix 'name' option issue ref: #3039 — committed to kazupon/vue by kazupon 8 years ago
- fix 'name' option issue (#3040) ref: #3039 — committed to vuejs/vue by kazupon 8 years ago
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 thecomponents:member where they are referenced (or globally as above), e.g.: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.
I think this is something that can be fixed since the expected behavior is reasonable.
@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
Indeed, name in single-file .vue component seems ignored.
I am running into this right now
@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:Defining them in the
components:member in the app or another component makes them only available to the template used there.@iambrennanwalsh thanks that’s helpful but the fact that you use the word
nameas the component’s name in this example couldn’t be more confusing.I actually think that, given the context of this issue (back to its very title), there was no worse word to choose from in the whole English dictionary 😃
Hi! Thank you for your reporting!
You can use the
nameoptions at onlyVue.extend(). Please see the below document. http://vuejs.org/api/#nameI think that you can resolve with a way the below jsfiddle URL. http://jsfiddle.net/kazupon/7u1xpaoh/1/
If any of the following is inaccurate, please feel free to let me know. I’m not an expert on the specifics, I’ve just been working with Vue.js for the past 3 weeks, and i thought I’d share what worked for me.
Specifying the ‘name’ within the Single File Component as instructed to do so above, did nothing for me. Instead what worked for me, was importing the component, and then assigning it a name within “components” of the root Vue instance…
Heres the Single File Component (name.vue). And below is the root Vue Instance (root.vue). It may be important to note that root.vue is then required() into my main.js which is where I actually import Vue source files.
I can now render this component within #root using…
I tried to dynamically register .vue components globally, but I have the same errors.
Can you explain what you did? And provide some code examples please. Thanks!
Dynamically importing the single-file component solved the issue for me.