// Component.vue
const block = (
<div
class="block"
onClick="handleClick"
<!-- here may go other prop definitions, perhaps complex ones -->
>
Block that should be reused
</div>
);
return (
<div class="container">
<div class="header">
Header content
{!isCompact && block}
</div>
<div class="footer">
Footer content
{isCompact && block}
</div>
</div>
);
// Component.vue
<template>
<div class="container">
<div class="header">
Header content
<div v-if="!isCompact"
class="block"
@click="handleClick">
Block that should be reused
</div>
</div>
<div class="footer">
Footer content
<div v-if="isCompact"
class="block"
@click="handleClick">
Block that should be reused
</div>
</div>
</div>
</template>
npm i @vueuse/core
// Component.vue
<script setup lang="ts">
import { createReusableTemplate } from '@vueuse/core'
const [DefineTemplate, ReuseTemplate] = createReusableTemplate()
</script>
// Component.vue
<template>
<DefineTemplate>
<div
class="block"
@click="handleClick">
Block that should be reused
</div>
</DefineTemplate>
<div class="container">
<div class="header">
Header content
<ReuseTemplate v-if="!isCompact" />
</div>
<div class="footer">
Footer content
<ReuseTemplate v-if="isCompact" />
</div>
</div>
</template>
// Component.vue
<template>
<DefineTemplate>
<div>Reused block A</div>
</DefineTemplate>
<ReuseTemplate />
<!-- registers another template instead -->
<DefineTemplate>
<div>Reused block B</div>
</DefineTemplate>
<!-- will now render new template -->
<ReuseTemplate />
</template>
// Output:
// Reused block A
// Reused block B
// Component.vue
<script setup>
import { createReusableTemplate } from '@vueuse/core'
const [DefineBlockA, ReuseBlockA] = createReusableTemplate()
const [DefineBlockB, ReuseBlockB] = createReusableTemplate()
</script>
<template>
<DefineBlockA>
<div>Reused block A</div>
</DefineBlockA>
<DefineBlockB>
<div>Reused block B</div>
</DefineBlockB>
<div class='text-comment'><!-- the two can exist simultaneously --></div>
<ReuseBlockA />
<ReuseBlockB />
</template>
// Output:
// Reused block A
// Reused block B
// Component.vue
const renderBlock = (className: string) => (
<div
class={`block ${className}`}
onClick="handleClick">
Block that should be reused and customized.
</div>
);
return (
<div class="container">
<div class="header">
Header content
{!isCompact && renderBlock("full")}
</div>
<div class="footer">
Footer content
{isCompact && renderBlock("compact")}
</div>
</div>
);
// Component.vue
<script setup lang="ts">
import { createReusableTemplate } from '@vueuse/core'
const [DefineTemplate, ReuseTemplate] = createReusableTemplate<{ className: string }>()
</script>
// Component.vue
<template>
<DefineTemplate v-slot="{ className }">
<div
:class="['block', className]"
@click="handleClick">
Block that should be reused and customized.
</div>
</DefineTemplate>
<div class="container">
<div class="header">
Header content
<ReuseTemplate v-if="!isCompact" className="full" />
</div>
<div class="footer">
Footer content
<ReuseTemplate v-if="isCompact" className="compact" />
</div>
</div>
</template>
// Component.vue
const renderBlock = (className: string, content: ReactNode) => (
<div
class={`block ${className}`}
onClick="handleClick">
Block that should be reused with custom content.
Custom content: {content}
</div>
);
return (
<div class="container">
<div class="header">
Header content
{!isCompact && renderBlock(
"full",
<div>Full content</div>
)}
</div>
<div class="footer">
Footer content
{isCompact && renderBlock(
"compact",
<div>Compact content</div>
)}
</div>
</div>
);
// Component.vue
<template>
<DefineTemplate v-slot="{ className, $slots }">
<div
:class="['block', className]"
@click="handleClick">
Block that should be reused with custom content.
Custom content:
<!-- To render the slot -->
<component :is="$slots.default" />
</div>
</DefineTemplate>
<div class="container">
<div class="header">
Header content
<ReuseTemplate v-if="!isCompact" className="full">
<div>Full content</div>
</ReuseTemplate>
</div>
<div class="footer">
Footer content
<ReuseTemplate v-if="isCompact" className="compact">
<div>Compact content</div>
</ReuseTemplate>
</div>
</div>
</template>