Vue.js 3.0 Tutorial
Vue.js 3.0 Component Advanced
Vue.js 3.0 Transitions & Animations
Vue.js 3.0 Reusable & Combinable
Vue.js 3.0 Advanced
Vue.js 3.0 Tools
Vue.js 3.0 Scale
Vue.js 3.0 Accessibility
Vue.js 3.0 Migrating from Vue2
Vue.js 3.0 Contribute Documentation
Vue.js 3.0 API References
Vue.js 3.0 Style Guide
One of the great new features introduced with Vue 3 is the support for Fragments. Fragments are essentially multiple root nodes in your component template. In Vue 2.x, every component's template was required to have one and only one root element, but that restriction is no longer present in Vue 3.
Let's see how we can use Fragments in a Vue 3 component:
<template> <h1>Hello</h1> <h2>Vue 3</h2> </template> <script> export default { name: 'MyComponent' } </script>
In this example, the template
has two root nodes, h1
and h2
. This was not possible in Vue 2, but in Vue 3 this is perfectly fine.
This feature is helpful in avoiding unnecessary wrapper elements and makes your HTML cleaner and more semantic.
It's worth noting that most styling and transitions which you might apply on the root node will now need to be applied individually to each top-level node. This is because there is no single root element to serve as the single source of styling or transitions when using Fragments.
Also, v-if
and v-for
directives can't be used directly on the Fragment. Instead, they should be used within a single node inside the Fragment.
Fragments are a straightforward feature in Vue 3 but can drastically simplify your component templates and the overall structure of your application.
Advantages of Using Fragments in Vue 3.0:
<template> <div> <p>Content 1</p> <p>Content 2</p> </div> </template>
Using fragments:
<template> <> <p>Content 1</p> <p>Content 2</p> </> </template>
Vue 3.0 Fragment Key Attribute:
v-for
loop, you can add a key
attribute to help Vue identify each fragment.<template> <div> <template v-for="(item, index) in items" :key="index"> <p>{{ item.text }}</p> </template> </div> </template>
Using fragments:
<template> <> <template v-for="(item, index) in items" :key="index"> <p>{{ item.text }}</p> </template> </> </template>
Handling Multiple Root Elements with Fragments in Vue 3.0:
<template> <div> <p v-if="condition">Content A</p> <p v-else>Content B</p> </div> </template>
Using fragments:
<template> <> <p v-if="condition">Content A</p> <p v-else>Content B</p> </> </template>
Vue 3.0 Conditional Rendering with Fragments:
<template> <div v-if="showContent"> <p>Conditional Content</p> </div> </template>
Using fragments:
<template> <template v-if="showContent"> <p>Conditional Content</p> </template> </template>
Vue 3.0 Fragments and Reactivity:
<template> <> <p>{{ message }}</p> </> </template> <script> export default { data() { return { message: 'Reactive Content', }; }, }; </script>
Dynamic Fragments in Vue 3.0:
<template> <template v-if="condition"> <p>Dynamic Content</p> </template> </template>
Vue 3.0 Fragments vs Div Wrappers:
Without fragments:
<template> <div> <p>Content A</p> <p>Content B</p> </div> </template>
Using fragments:
<template> <> <p>Content A</p> <p>Content B</p> </> </template>
Vue 3.0 Handling Transitions with Fragments:
<template> <transition name="fade"> <template v-if="showContent"> <p>Fading Content</p> </template> </transition> </template>
Using fragments:
<template> <transition name="fade"> <template v-if="showContent"> <p>Fading Content</p> </template> </transition> </template>
Vue 3.0 Fragments and JSX:
<script setup> import { ref } from 'vue'; const showContent = ref(true); return () => ( <> <p v-if="showContent">JSX Content</p> </> ); </script>