In Vue.js why do we have to export components after importing them?
Components in vue
can be tricky. If you haven't yet, I would highly recommend reading the documentation on the vue.js website on how component registration works, specifically, as tony19 mentions global and local registration. The code example you show in your screenshot is actually doing a couple of things. For one, it is making the components available locally, and only locally (as in that .vue file) for use. In addition, it is making it available to the template as the key
you provide in the components
object, in this case, app-user-detail
and app-user-edit
instead of user-detail
and user-edit
.
Importantly, it should be mentioned that an import
is not actually required for this component registration to function. You could have multiple components defined in a single file. The components
key gives a way to identify what that component is using. So that import
isn't required, so vue
does require the components
key to understand what you are using as a component, and what is just other code.
Finally, as some of the other answers have alluded to, the components
key is not actually an export. The default signature of a vue
component requires an export
but this is not exporting the components listed under the components
key. What it is doing is letting vue
build in a top down manner. Depending on what the rest of your application setup looks like, you may be using single file components, or not. Either way, vue
will start with the top level vue instance
and work its way down through components, with the exception of global registration, no top level component knows which components are being used below it.
This means for vue
to render things properly, each component has to include a reference to the extra components it uses. This reference is exported as part of the higher level component (in your case User.vue
), but is not the component itself (UserDetail.vue
).
So it may appear that vue
requires a second export after import, but it is actually doing something else to allow the root vue instance to render your component.
As an aside, the vue documentation on this subject really is quite good, if you haven't already please take a look at the sections I linked above. There is an additional section on module import/export systems that seems highly relevant to what you are asking, you can find that here: Module-systems.
in
Vue.js
, after importing a component we must also export it.
I think you might be referring to the following lines in User.vue
and wondering why UserDetail
and UserEdit
are imported into the file and then exported in the script export's components
property:
import UserDetail from './UserDetail.vue';
import UserEdit from './UserEdit.vue';
export default {
components: {
appUserDetail: UserDetail,
appUserEdit: UserEdit
}
}
vue-loader
expects the script export of a .vue
file to contain the component's definition, which effectively includes a recipe to assemble the component's template. If the template contained other Vue components, the definition of the other components would need to be provided, otherwise known as component registration. As @Sumurai8 indicated, the import of the .vue
files itself does not register the corresponding single-file-components; rather those components must be explicitly registered in the importer's components
property.
For example, if App.vue
's template contained <user />
and User.vue
were defined as:
<template>
<div class="user">
<app-user-edit></app-user-edit>
<app-user-detail></app-user-detail>
</div>
</template>
<script>
export default {
name: 'user'
}
</script>
...the User
component would be rendered blank, and you would see the following console errors:
[Vue warn]: Unknown custom element: <app-user-edit> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
[Vue warn]: Unknown custom element: <app-user-detail> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
demo 1
When Vue attempts to render <user />
inside App.vue
's template, Vue doesn't know how to resolve the inner <app-user-detail>
and <app-user-edit>
because their component registrations are missing. The errors can be resolved by local component registration in User.vue
(i.e., the components
property shown above).
Alternatively, the errors can be resolved with global component registration of UserDetail
and UserEdit
, which would obviate the local registration in User.vue
. Note that global registration must be done before creating the Vue instance. Example:
// main.js
import Vue from 'vue';
import UserDetail from '@/components/UserDetail.vue';
import UserEdit from '@/components/UserEdit.vue';
Vue.component('app-user-detail', UserDetail);
Vue.component('app-user-edit', UserEdit);
new Vue(...);
demo 2