Implementing Slot Props in Vue with TypeScript
Slot props allow you to pass data down from a parent component to a child component's slot, enabling dynamic content injection and greater component reusability. This challenge will guide you in creating a Vue component that utilizes slot props to customize its behavior and appearance based on data passed from its parent. Successfully completing this challenge demonstrates a strong understanding of Vue's slot mechanism and TypeScript's type safety.
Problem Description
You are tasked with creating a Card component in Vue.js using TypeScript. This Card component should accept a title prop and a footer prop. The title prop is a string representing the card's title, which should be displayed prominently. The footer prop is an object containing optional properties: icon (a string representing an icon class, e.g., "fas fa-check-circle") and text (a string representing the footer text). The Card component should render a basic card structure, displaying the title and, if provided, the footer with its icon and text. The footer content should be rendered within a named slot called "footer-content".
Key Requirements:
- The
Cardcomponent must be written in TypeScript. - The
titleprop must be a string. - The
footerprop must be an object with optionalicon(string) andtext(string) properties. - The component must render the title.
- If a
footerprop is provided, it should render an icon (if present) and text within the "footer-content" slot. - The component should be reusable and adaptable to different footer content.
Expected Behavior:
When a parent component uses the Card component and provides a title and a footer object with both icon and text, the card should display the title and the footer with the specified icon and text within the "footer-content" slot. If only one of icon or text is provided, only that property should be rendered. If no footer is provided, the "footer-content" slot should remain empty.
Edge Cases to Consider:
- What happens if the
iconprop is an empty string? Should it be rendered or skipped? (Assume it should be skipped). - What happens if the
textprop is null or undefined? (Assume it should be skipped). - What happens if the
footerprop is null or undefined? (The footer should not be rendered).
Examples
Example 1:
Input:
<Card title="Welcome!" footer={{ icon: "fas fa-smile", text: "Success!" }} />
Output:
<div class="card">
<h1>Welcome!</h1>
<div class="card-footer">
<i class="fas fa-smile"></i>
<span>Success!</span>
</div>
</div>
Explanation: The card displays the title "Welcome!" and the footer with the smile icon and the text "Success!".
Example 2:
Input:
<Card title="Important Notice" footer={{ text: "Please read carefully." }} />
Output:
<div class="card">
<h1>Important Notice</h1>
<div class="card-footer">
<span>Please read carefully.</span>
</div>
</div>
Explanation: The card displays the title "Important Notice" and the footer with only the text "Please read carefully." because the icon is missing.
Example 3:
Input:
<Card title="Simple Card" />
Output:
<div class="card">
<h1>Simple Card</h1>
</div>
Explanation: The card displays the title "Simple Card" and no footer because no footer prop was provided.
Constraints
- The
titleprop must be a string. - The
iconprop (within thefooterobject) must be a string. - The
textprop (within thefooterobject) must be a string. - The component should be reasonably performant (no unnecessary re-renders).
- Use standard Vue.js and TypeScript practices.
Notes
- Consider using template literals for cleaner HTML generation.
- Think about how to handle optional properties in the
footerobject using TypeScript's optional properties and conditional rendering. - You can use any CSS framework or styling approach you prefer for the card's appearance. The focus is on the slot prop implementation, not the styling.
- The
Cardcomponent should be a single-file component (.vue). - Assume the
fasicon classes are available (e.g., from Font Awesome).