Implementing Named Slots in Vue with TypeScript
Named slots in Vue.js provide a powerful mechanism for component composition and customization. This challenge asks you to build a reusable component that utilizes named slots to allow parent components to inject specific content into designated areas within the child component. This is a common pattern for creating flexible and adaptable UI elements.
Problem Description
You are tasked with creating a Card component that accepts named slots for its header, body, and footer. The Card component should render a basic card structure with placeholders for these slots. The parent component will then be able to provide custom content for each slot, effectively customizing the card's appearance and functionality.
What needs to be achieved:
- Create a
Cardcomponent with three named slots:header,body, andfooter. - The
Cardcomponent should render a basic HTML structure representing a card (e.g., adivwith a specific class). - The slots should be rendered in their designated positions within the card structure.
- The component should be written in TypeScript.
Key Requirements:
- The
Cardcomponent must be a functional component. - The component must correctly render the content passed to each named slot.
- The component should handle cases where a slot is not provided (i.e., the parent component doesn't pass content for a specific slot). In such cases, the slot area should be rendered as empty.
Expected Behavior:
When a parent component uses the Card component and provides content for one or more named slots, the content should be rendered in the corresponding slot area within the card. If a slot is not provided, the slot area should remain empty.
Edge Cases to Consider:
- What happens if the parent component provides
nullorundefinedas the content for a slot? The component should gracefully handle this and render an empty slot. - What happens if the parent component provides a complex data structure (e.g., an array of elements) as the content for a slot? The component should render the content as is.
- Consider how to handle potential errors if the slot content is not valid HTML. (While error handling isn't strictly required for this challenge, it's a good consideration for real-world applications.)
Examples
Example 1:
Input: Parent Component:
<template>
<Card>
<template #header>
<h1>My Card Title</h1>
</template>
<template #body>
<p>This is the main content of the card.</p>
</template>
<template #footer>
<button>Learn More</button>
</template>
</Card>
</template>
<script setup lang="ts">
import Card from './Card.vue';
</script>
Output:
<div class="card">
<div>
<h1>My Card Title</h1>
</div>
<div>
<p>This is the main content of the card.</p>
</div>
<div>
<button>Learn More</button>
</div>
</div>
Explanation: The parent component provides content for all three named slots. The Card component renders the provided content in the corresponding slot areas.
Example 2:
Input: Parent Component:
<template>
<Card>
<template #header>
<h2>Card Header</h2>
</template>
</Card>
</template>
<script setup lang="ts">
import Card from './Card.vue';
</script>
Output:
<div class="card">
<div>
<h2>Card Header</h2>
</div>
<div></div>
<div></div>
</div>
Explanation: The parent component only provides content for the header slot. The body and footer slots are rendered as empty.
Example 3: (Edge Case)
Input: Parent Component:
<template>
<Card>
<template #body>
null
</template>
</Card>
</template>
<script setup lang="ts">
import Card from './Card.vue';
</script>
Output:
<div class="card">
<div></div>
<div></div>
<div></div>
</div>
Explanation: The parent component provides null for the body slot. The Card component renders the body slot as empty.
Constraints
- The
Cardcomponent must be a functional component using the<script setup>syntax. - The component must be written in TypeScript.
- The card structure should be a
divwith the class "card". The header, body, and footer should be contained withindivelements inside the card. - The solution should be reasonably efficient. Avoid unnecessary DOM manipulations.
Notes
- Consider using the
slotprop to access the slot content. - The
Cardcomponent doesn't need to include any styling. Focus on the structure and slot rendering. - This challenge focuses on the core functionality of named slots. Error handling and advanced features are not required.
- Think about how to handle different data types passed to the slots. Vue will automatically handle rendering most valid JavaScript expressions.