Vue: Vue template compiler namespace support.

Created on 3 May 2017  路  11Comments  路  Source: vuejs/vue

What problem does this feature solve?

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.

What does the proposed API look like?

<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>

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:

components: {
   ...namespaceComponents('foo', [Counter])
}

All 11 comments

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?

Was this page helpful?
0 / 5 - 0 ratings