Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fragment component #449

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions active-rfcs/0000-fragment-component.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
- Start Date: 2022-05-17
- Target Major Version: 3.x
- Reference Issues:
- Implementation PR:

# Summary

Add `fragment` built-in component that acts as a `<template>` empty wrapper tag.

# Basic example

## Conditional wrapper component

```html
<template>
<WrapperComponent v-if="shouldWrap">
<img src="cat.jpg" alt="Cat" />
</WrapperComponent>
<img v-else src="cat.jpg" alt="Cat" />
</template>
```

## `Fragment` component

```html
<template>
<component :is="shouldWrap ? WrapperComponent : 'fragment'">
<img src="cat.jpg" alt="Cat" />
</component>
</template>
```

# Motivation

There are cases when some markup should be conditionally wrapped within a tag\component or not wrapped at all. Right now you have 2 options on how to deal with that: either duplicate the markup or extract that code into a separate component. Both are not ideal: duplicate code is invisibly coupled (changes in one copy should be reflected in all other copies), extracting into component is cumbersome. It gets more tedious when you have multiple of those cases in a single component.

You might also want to create your own kind of `fragment` component. But it will recieve all the custom directives from the parent, which will result in errors.

Example:

```html
<component :is="shouldWrap ? 'div' : 'MyFragmentComponent'" v-custom-directive>
<img src="cat.jpg" alt="Cat">
</component>
```

# Detailed design

`<component is="fragment">` should be compiled into `h('fragment')`. Vue renderer should be updated accordingly to support rendering fragments that way.

`<component is="fragment">foo</component>` should produce only `foo` as a render result.

Custom directives applied to a `fragment` component should be discarded.

# Drawbacks

Possibly a duplicate of `<template>` tag functionality. See **Unresolved questions** section.

# Alternatives

Another approach could be to add suppoort for `null` or `undefined` as the `<component>` `is` attribute.

# Adoption strategy

This is not a breaking change. All the exisiting components that already define a `Fragment` component should continue to function without any issues.

# Unresolved questions

Should we allow for `<fragment>` tag to work the same way?

Should it be `<>` instead of `<fragment>`?

Would that conflict with the `<template>` tag?