Skip to content

Proposal: Multiple components in .vue files #9852

@cameronhimself

Description

@cameronhimself

What problem does this feature solve?

Other frontend frameworks, notably React, make it quick and easy to create many small components in a single file. This pattern promotes code reuse, component composition, and DRYness.

While Vue has this ability, it feels hacky and sacrifices much of the clarity and usability that .vue files provide.

This aim of this proposal is to define a clear and intuitive API for defining multiple components in a single .vue file.

What does the proposed API look like?

<component>

The <component> element is the building block of multi-component .vue files. Used as a top-level tag in .vue files, it's effectively a self-contained "single-file component", and it can contain anything that is valid in single-file components as they're currently defined. A .vue file can contain any number of <component> elements. They are evaluated from top to bottom—no hoisting. The element accepts two properties that control its availability to other parts of the code:

  • name (string, no default)

    The name of the variable that the component is assigned to. Components defined lower in the file can reference this component by its name. Additionally, if the component is exported (see below), this is the name under which it will be exported.

  • export (boolean, default false)

    Whether or not the component is exported. If a component is exported, but doesn't have a name, it will be the default export. More than one exported component without a name would create multiple default exports, and is therefore an error. All components must have either name or export or both.

By using the <component> element, individual .vue files gain a great deal more flexibility and power. They can compose a single exported component from many small child components, they can export many small components used throughout an application, they can export a main default component and less frequently used named components, and so on.

Examples

An isolated component (Foo) only used by another component in the same file:
<component name="Foo">...</component>
<component export>
    <script>export default { components: { Foo } };</script>
    <template><foo /></template>
</component>
Named and default exports:
<component export name="Foo">...</component>
<component export name="Bar">...</component>
<component export>...</component>

These would be imported in another file with import Baz, { Foo, Bar } from './Baz.vue';

An illegal file due to multiple default exports
<component export>...</component>
<component export>...</component>
An illegal file, because it combines the multi-component format and the single-component format
<component name="Foo">...</component>
<script>export default { components: { Foo } };</script>
<template><foo /></template>

Backwards compatibility

The addition of the <component> element would not be a breaking change—single-file components with no top-level <component> tags would continue to function exactly as they do today. As mentioned in the example above, combining the single-component format with the multi-component format is an error.

A potential point of conflict is the existing <component> tag than can be used in templates. I don't foresee this being a problem, since the usage of <component> as a top-level tag in .vue files is well defined, but I can't say for sure.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions