Hone logo
Hone
Problems

Dynamic Content Rendering with Scoped Slots in Vue

Scoped slots are a powerful feature in Vue.js that allow parent components to render content provided by child components, while still having access to data and methods within the child. This challenge will task you with building a reusable Card component that utilizes scoped slots to provide flexible content rendering options for its users. Understanding and implementing scoped slots is crucial for creating highly customizable and reusable Vue components.

Problem Description

You are tasked with creating a Card component that accepts a title and a slot for the card's content. The Card component should render a basic card structure (a div with a specific class) and display the provided title. The content within the card should be rendered using a scoped slot named default. The Card component should also expose a isHighlighted prop, which, when true, adds a highlight class to the card.

Key Requirements:

  • Create a Card.vue component with a title prop (string) and an isHighlighted prop (boolean).
  • The component should render a div with the class card.
  • The component should display the title prop within an h2 element inside the card.
  • The component should use a scoped slot named default to render the card's content.
  • If isHighlighted is true, the card div should also have the class card--highlighted.
  • The component should be written in TypeScript.

Expected Behavior:

When a parent component uses the Card component and provides a title and content via the default slot, the Card component should render a card with the title displayed and the provided content rendered within the card. The isHighlighted prop should control the presence of the card--highlighted class.

Edge Cases to Consider:

  • What happens if no content is provided for the default slot? The card should still render correctly with just the title.
  • What happens if isHighlighted is not provided? It should default to false.
  • Ensure the TypeScript types are correctly defined for props and slot usage.

Examples

Example 1:

Input:
<template>
  <Card title="My Awesome Card" isHighlighted>
    <p>This is the content of the card.</p>
    <button>Click Me</button>
  </Card>
</template>

<script setup lang="ts">
import Card from './Card.vue';
</script>

Output:

<div class="card card--highlighted">
  <h2>My Awesome Card</h2>
  <p>This is the content of the card.</p>
  <button>Click Me</button>
</div>

Explanation: The Card component renders with the title "My Awesome Card", the content (paragraph and button), and the card--highlighted class because isHighlighted is true.

Example 2:

Input:
<template>
  <Card title="Simple Card" />
</template>

<script setup lang="ts">
import Card from './Card.vue';
</script>

Output:

<div class="card">
  <h2>Simple Card</h2>
</div>

Explanation: The Card component renders with the title "Simple Card" and no highlight class because isHighlighted is not provided (defaults to false).

Example 3: (Edge Case - No Content)

Input:
<template>
  <Card title="Empty Card" />
</template>

<script setup lang="ts">
import Card from './Card.vue';
</script>

Output:

<div class="card">
  <h2>Empty Card</h2>
</div>

Explanation: The Card component renders with the title "Empty Card" and no highlight class, even though no content is provided for the slot.

Constraints

  • The component must be written in TypeScript.
  • The component must use the defineProps and slots APIs for Vue 3 Composition API.
  • The card class should be card. The highlighted card class should be card--highlighted.
  • The title element should be an h2 element.
  • The solution should be a single Card.vue file.

Notes

  • Consider using the withDefaults option in defineProps to provide a default value for the isHighlighted prop.
  • Remember that scoped slots allow you to pass data from the child component to the slot's content. While this challenge doesn't require passing data, it's a key concept to keep in mind.
  • Focus on creating a clean and well-structured component that adheres to Vue best practices.
  • Test your component thoroughly with different inputs and scenarios to ensure it behaves as expected.
Loading editor...
typescript