vue-frag

Vue 2 fragment directive to return multiple root elements
<template>
<div v-frag>
<div>Root element 1</div>
<div>Root element 2</div>
<div>Root element 3</div>
</div>
</template>
🙋♂️ Why?
- ✅ Multiple root nodes Without creating a functional component!
- 🔥 SSR Unwraps the root element on client-side post-hydration!
- ⚡️ Directives Supports
v-if
, v-for
, and v-html
! - 🐥 Tiny Only
816 B
!
🚀 Install
npm i vue-frag
🚦 Quick Setup
Register globally
Make it available anywhere in your Vue application.
import frag from 'vue-frag';
Vue.directive('frag', frag);
Register locally
Explicitly register it to a component you want to use it in.
...
<script>
import frag from 'vue-frag';
export default {
directives: {
frag
},
...
};
</script>
👨🏻🏫 Examples
Returning multiple root nodes 
<template>
<div v-frag> <!-- This element will be unwrapped -->
<div v-for="i in 10">
{{ i }}
</div>
</div>
</template>
Unwrapping the root node from a component
<template>
<div>
<!-- Unwraps the root node of some-custom-component -->
<some-custom-component v-frag />
</div>
</template>
Supports v-if too
<template>
<div v-frag>
<template v-if />
</div>
</template>
Access fragment DOM nodes
<template>
<div v-frag>
Hello world
</div>
</template>
<script>
export default {
mounted() {
console.log(this.$el.frag)
}
}
</script>
💁♀️ FAQ
How does this work?
Vue associates vNodes with specific DOM references so once a component has mounted, the DOM nodes can be moved around and Vue will still be able to mutate them by reference. The Frag directive simply replaces the root element of a component in the DOM with it's children upon DOM insertion, and monkey-patches native properties like parentNode
on the children to make Vue think they're still using the component root element.
Does v-show
work?
Unfortunately not. v-show
works by setting style="display: none"
on the root element of the target component, and with vue-frag
unwrapping and removing the root element, there would be no grouping-element to apply the display: none
to. If the fragment returned elements, it's possible to apply it to each child-node, but it's possible for them to be text-nodes which cannot be styled.