Vue 2 Fragment Directive
vue-frag provides Vue 3's native fragment functionality to Vue 2 applications, allowing components to render multiple root elements without an artificial wrapper div. This addresses a core limitation in Vue 2's template syntax. The current stable version is 1.4.3. Releases are made on an as-needed basis, primarily for bug fixes and minor enhancements related to Vue 2 compatibility. Key differentiators include support for server-side rendering (SSR), compatibility with core Vue directives like `v-if`, `v-for`, and `v-html`, and offering both a Component API (`<fragment>`) and a Directive API (`v-frag`) for flexible usage. It can also be paired with `vue-frag-plugin` for automatic fragment injection, simplifying development by allowing multiple root nodes directly in SFCs.
Common errors
-
[Vue warn]: Failed to resolve component: Fragment
cause The `Fragment` component has not been registered or imported correctly in the current Vue instance or component.fixEnsure you have `import { Fragment } from 'vue-frag';` in your script and added `Fragment` to your component's `components` option, or globally registered it with `Vue.component('Fragment', Fragment);`. -
[Vue warn]: Failed to resolve directive: frag
cause The `v-frag` directive has not been registered or imported correctly in the current Vue instance or component.fixEnsure you have `import frag from 'vue-frag';` in your script and added `frag` to your component's `directives` option, or globally registered it with `Vue.directive('frag', frag);`. -
TypeError: Cannot read properties of null (reading 'nextSibling') or similar DOM manipulation errors related to element removal/insertion.
cause This error often occurs in older versions of `vue-frag` when the directive or component attempts to dynamically detect or update sibling nodes during complex DOM operations, especially when fragments become empty or elements are dynamically added/removed.fixUpgrade `vue-frag` to the latest version (1.4.3 or newer) as several bug fixes in 1.2.x and 1.4.x releases addressed these specific issues related to DOM patching and sibling detection.
Warnings
- gotcha vue-frag is specifically designed for Vue 2. It is not necessary for Vue 3 applications, as Vue 3 provides native fragment support out-of-the-box. Attempting to use it in Vue 3 may lead to unexpected behavior or errors.
- gotcha The `Fragment` component or `v-frag` directive must be registered either locally within each component's `components` or `directives` option, or globally via `Vue.component` or `Vue.directive`. Forgetting to register will result in 'Failed to resolve component/directive' warnings.
- gotcha Older versions of `vue-frag` (prior to 1.4.3) had known issues with compatibility when components utilizing fragments were wrapped with Vue's built-in `<keep-alive>` component, leading to incorrect DOM updates or rendering issues.
- gotcha When using the `v-frag` directive on a component, it will unwrap the *root node* of that component, effectively removing it from the DOM. Be mindful of this behavior, as it might alter expected DOM structure if not intended.
Install
-
npm install vue-frag -
yarn add vue-frag -
pnpm add vue-frag
Imports
- Fragment
const Fragment = require('vue-frag').Fragmentimport { Fragment } from 'vue-frag' - frag
const frag = require('vue-frag')import frag from 'vue-frag'
- Global Component Registration
Vue.component('Fragment', require('vue-frag').Fragment)import { Fragment } from 'vue-frag'; Vue.component('Fragment', Fragment); - Global Directive Registration
Vue.directive('frag', require('vue-frag').default)import frag from 'vue-frag'; Vue.directive('frag', frag);
Quickstart
<template>
<fragment>
<!-- This root element will not exist in the DOM, allowing multiple siblings -->
<li>Element 1</li>
<li>Element 2</li>
<li v-if="showThirdElement">Element 3 conditionally rendered</li>
<div v-for="item in items" :key="item.id">
Item: {{ item.name }}
</div>
</fragment>
</template>
<script lang="ts">
import { Fragment } from 'vue-frag';
import Vue from 'vue';
export default Vue.extend({
components: {
Fragment
},
data() {
return {
showThirdElement: true,
items: [
{ id: 1, name: 'Apple' },
{ id: 2, name: 'Banana' }
]
};
}
});
</script>