Skip to content

Instantly share code, notes, and snippets.

@loilo
Last active April 11, 2022 14:30
Show Gist options
  • Select an option

  • Save loilo/00fd0c5ba8118bee4f9af20756ce87ce to your computer and use it in GitHub Desktop.

Select an option

Save loilo/00fd0c5ba8118bee4f9af20756ce87ce to your computer and use it in GitHub Desktop.
Unwrap Component for Vue 2

Unwrap Component for Vue 2 and Vue 3

Here's a demo of the Unwrap component in the Vue SFC Playground (Vue 3).

Conditionally unwrap the contained components.

<template>
  <div>
    <label>
      <input type="checkbox" v-model="singleList" />
      Single list
    </label>

    <Unwrap :if="!singleList">
      <ul>
        <Unwrap :if="singleList">
          <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
          </ul>
          <ul>
            <li>4</li>
            <li>5</li>
            <li>6</li>
          </ul>
        </Unwrap>
      </ul>
    </Unwrap>
  </div>
</template>

<script>
import Unwrap from './unwrap.js'

export default {
  components: { Unwrap },
  data: () => ({
    singleList: false
  })
}
</script>
export default {
functional: true,
props: {
if: {
type: [Boolean, Function],
default: true
}
},
render(h, ctx) {
const children = ctx.children
const functionalUnwrap = typeof ctx.props.if === 'function'
if (!functionalUnwrap && !ctx.props.if) return children
let reducer = functionalUnwrap
? (carry, current, index, array) => [
...carry,
current.children && ctx.props.if(current, index, array)
? current.children
: current
]
: (carry, current) => [...carry, current.children || current]
return children.reduce(reducer, [])
}
}
export default {
props: {
if: {
type: [Boolean, Function],
default: true
}
},
setup(props, { slots }) {
return () => {
const functionalUnwrap = typeof props.if === 'function'
const children = slots.default()
if (!functionalUnwrap && !props.if) return children
let reducer = functionalUnwrap
? (carry, current, index, array) => [
...carry,
current.children && props.if(current, index, array)
? current.children
: current
]
: (carry, current) => [...carry, current.children || current]
return children.reduce(reducer, [])
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment