Giter Site home page Giter Site logo

privatenumber / vue-frag Goto Github PK

View Code? Open in Web Editor NEW
214.0 3.0 14.0 759 KB

๐Ÿคฒ Create Fragments (multiple root-elements) in Vue 2

License: MIT License

JavaScript 21.88% TypeScript 78.12%
vue fragment directive ssr multiple root nodes vuejs component

vue-frag's Introduction

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!

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!
๐Ÿ”ฅ Pro-tip

Want to be able to just have multiple root-nodes in your SFC without a wrapper? Use vue-frag-plugin to automatically inject vue-frag so that you can return multiple root nodes without a fragment component!

Premium sponsor banner

๐Ÿš€ 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 -->
        <SomeCustomComponent 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>

Premium sponsor banner

๐Ÿ’โ€โ™€๏ธ 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

Sponsors

Premium sponsor banner Premium sponsor banner

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.