Often it's needed to wrap some part of a template in a wrapper <div>
for example. It seems easy using v-if
but we have a duplication we'd like to avoid:
<div v-if="isWrapped" class="wrapper">
<!-- some big chunk of markup -->
</div>
<template v-else>
<!-- the same big chunk -->
</template>
Let's explore our options how we can solve this task without duplication. Let's call our component <wrap>
and our component that wraps the content a wrapper. Sure it should be functional since there's no state to keep.
Our first option would be simple. We support a wrapper component and its props:
import { h } from 'vue';
export default function Wrap({wrapper, ...props}, {slots}){
return wrapper ? h(wrapper, props, slots.default()) : slots.default();
}
Usage:
<script setup>
import { ref } from 'vue';
import Wrap from './Wrap';
const isWrapped = ref(false);
</script>
<template>
<wrap :wrapper="isWrapped && 'div'" :="{class: 'wrapper'}">
<p>
I'm wrapped
</p>
</wrap>
<button @click="isWrapped = !isWrapped">Toggle wrapper</button>
</template>
The result is pretty sufficient, you can use any wrapper component with a default slot. But a problem here is that for more complex cases like having multiple nested wrappers we should define the wrapper outside our markup since having a functional wrapper component inside :wrapper
property looks pretty messy. In the next posts of this series we'll explore other options of defining our conditional wrap component.
What's your thoughts?
Please Register or Login to your account to be able to submit your comment.