Having ability to have a more structured template. Sometimes I end up with a lot of components (even with same name so I rename them) inside one component and I feel like it would be nice if I could namespace them.
<template>
<div>
<user:signup />
<user:authentication />
<statistics:counter />
<statistics:server-status />
</div>
</template>
<script>
import { Authentication, Signup } from 'user/components'
import { Counter, ServerStatus } from 'statistics/components'
export default {
components: {
user: { Authentication, Signup },
statistics: { Counter, ServerStatus }
}
}
</script>
This'd work really well for external component collections, who could put their elements under mdi:button, next:button and the like.
@just-nobody, true, vuetify for that purpose uses v- prefix
<template>
<div>
<user:same-name-comp />
<statistics:same-name-comp />
</div>
</template>
<script>
import user from 'user/components'
import statistics from 'statistics/components'
export default {
namespaces: {
user,
statistics
}
}
</script>
Is it this feature want to achieve?
namespaces doesn't seem like a very clear name. Namespaces for what? componentNamespaces seems a little long, though.
On a similar note, I'm not sure how vue could differentiate a namespace definition from a component definition under components. Example: user: { Authentication, Signup }, user in this case could just be an invalid component definition with Authentication and Signup properties.
@xujiongbo, yes, kinda like that but I don't like namespace because it's not clear enough.
@just-nobody, what I was thinking is Uppercasing or componentNamespaces or maybe something like:
const isComponent = obj => !!obj.render
const isNamespace = obj => !obj.render && Object.values(obj).every(isComponent)
But that conflicts with render name.
Or, as another option, is to not validate components prop values and then when $createElement gets a string containing a colon it looks into components[beforeColon][afterColon] ?
I'm not sure to understand what is missing here, you can already namespace components: http://jsfiddle.net/posva/9humt9c5/
It can look better with a helper but that can be done outside of Vue:
components: {
...namespaceComponents('foo', [Counter])
}
@posva, hmm, right, nice, never though about it, that's so obvious.
Thank you
@posva how would you do that with a component definition like this?
Vue.component('questions-list', require('../vue/surveys/editor/QuestionsList.vue'));
It actually throws an exception, if you try to namespace it:
[Vue warn]: Invalid component name: "surveys:questions-list". Component names can only contain alphanumeric characters and the hyphen, and must start with a letter
PS: Actually it's just a warning, but then I don't see why it's raised :)
@sebestenyb This can not be done with global component definition, I suppose you should register the component locally.
@posva Awesome solution. An actual implementation could be:
export function namespaceComponents(namespace, components) {
return Object.fromEntries(Object.entries(components).map(([key, value]) => [`${namespace}:${key}`, value]));
}
However this will throw a warning message if used like this:
components: {
...namespaceComponents('UI', {
Button
})
}
Invalid component name: "UI:Button". Component names should conform to valid custom element name in html5 specification.
So what about the warning message? Is there someway to disable this?
Most helpful comment
I'm not sure to understand what is missing here, you can already namespace components: http://jsfiddle.net/posva/9humt9c5/
It can look better with a helper but that can be done outside of Vue: