npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vue-frag

v1.4.3

Published

Vue 2 fragment directive to return multiple root elements

Downloads

80,433

Readme

vue-frag

Use Vue 3's Fragment feature in Vue 2 to return multiple root elements.

<template>
    <fragment> ⬅ This root element will not exist in the DOM

        <li>Element 1</li>
        <li>Element 2</li>
        <li>Element 3</li>
    </fragment>
</template>

<script>
import { Fragment } from 'vue-frag'

export default {
    components: {
        Fragment
    }
}
</script>

👉 Try it out on CodePen!

Support this project by ⭐️ starring and sharing it. Follow me to see what other cool projects I'm working on! ❤️

🌟 Features

  • ✅ 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!
  • 👩‍🔬 Battle-tested Checkout the tests here!

🚀 Install

npm i vue-frag

🚦 Quick Setup

You can either choose to use the Component or Directive API.

Component API

The Component API is designed to be used at the root of the template. It should feel intuitive to use and cover most use-cases.

Import Fragment and use it as the root element of your component:

<template>
    <fragment>
        Hello world!
    </fragment>
</template>

<script>
import { Fragment } from 'vue-frag'

export default {
    components: {
        Fragment
    }
}
</script>

Register globally

Globally registering the component lets you use it without needing to import it every time.

import { Fragment } from 'vue-frag'

Vue.component('Fragment', Fragment)

Directive API

Use the Directive API to have more nuanced control over placement. For example, if you want to unwrap the root node of a component on the usage-end.

The Component API uses the Directive API under the hood.

<template>
    <div v-frag>
        Hello world!
    </div>
</template>

<script>
import frag from 'vue-frag'

export default {
    directives: {
        frag
    }
}
</script>

Register globally

Make it available anywhere in your Vue application.

import frag from 'vue-frag'

Vue.directive('frag', frag)

👨🏻‍🏫 Examples

Returning multiple root nodes

Component API

<template>
    <fragment> <!-- This element will be unwrapped -->

        <div v-for="i in 10">
            {{ i }}
        </div>
    </fragment>
</template>

Directive API

<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

Use the Directive API to unwrap the root node of 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="isShown">
            Hello world!
        </template>
    </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

When would I want to return multiple root nodes?

Whenever you feel like the root-element of your component adds no value and is unnecessary, or is messing up your HTML output. This usually happens when you want to return a list of elements like <li>List Items</li> or <tr><td>Table Rows</td></tr> but you have to wrap it in a <div>.

In Vue 2, it's possible to return multiple nodes with a Functional Component but functional components are stateless (no data() or life-cycle hooks), doesn't support methods, doesn't have very good template support, and can lead to SSR bugs (eg. mismatching nodes).

Related VueJS Issues / Stackoverflow Qs:

How does this work?

vue-frag works by tricking Vue.js to think that the root element is still in the DOM, when it's actually not.

When vue-frag is applied to an element, it uses the inserted directive hook to swap the element out with its children to remove itself from the DOM. It then patches surrounding DOM nodes (eg. parent, sibling, children) to make them think that the element is still in the DOM.

Here are all the DOM APIs Vue.js uses that are patched:

Does v-show work?

Like in Vue 3, v-show does not work on components that return a fragment. v-show works by setting style="display: none" on the root element of the target component. With vue-frag 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.

👨‍👩‍👧 Related

  • vue-frag-plugin - Build-time plugin to seamlessly use multiple root nodes
  • vue-subslot - 💍 pick out specific elements from component <slot>s
  • vue-vnode-syringe - 🧬 Add attributes and event-listeners to <slot> content 💉
  • vue-proxi - 💠 Tiny proxy component
  • vue-pseudo-window - 🖼 Declaratively interface window/document in your Vue template
  • vue-v - render vNodes via component template