Hone logo
Hone
Problems

Vue Local Component Registration Challenge

This challenge focuses on a fundamental aspect of Vue.js development: the efficient and organized use of local components. Understanding how to import and register components locally within a parent component is crucial for building maintainable and scalable Vue applications. You will practice registering and using these components to create a dynamic user interface.

Problem Description

Your task is to create a Vue 3 application using TypeScript that demonstrates the effective use of locally registered components. You will be given a parent component, App.vue, and you need to create three distinct child components: Button.vue, Card.vue, and Modal.vue. These child components should be imported and registered locally within App.vue.

Requirements:

  1. Button.vue: This component should render a simple <button> element. It should accept a label prop (string) to display as the button's text. It should also emit a click event when the button is clicked.
  2. Card.vue: This component should render a styled card container. It should accept a title prop (string) to display as the card's heading. It should also use a default slot to render any content placed inside the card.
  3. Modal.vue: This component should render a modal dialog. It should accept an isOpen prop (boolean) to control its visibility. When isOpen is true, the modal should be displayed, otherwise it should be hidden. The modal should contain a title (can be hardcoded or passed as a prop) and a close button (using the Button.vue component) that emits a close event when clicked.
  4. App.vue: This is your main application component.
    • It must import and locally register Button.vue, Card.vue, and Modal.vue.
    • It should maintain a reactive state variable, isModalOpen, which controls the visibility of the Modal.vue component.
    • It should display a Button.vue component that, when clicked, sets isModalOpen to true.
    • It should render a Card.vue component containing some arbitrary content.
    • It should render the Modal.vue component, bound to the isModalOpen state.
    • The Modal.vue component within App.vue should listen for the close event emitted by its internal Button.vue and set isModalOpen to false.

Expected Behavior:

  • When the application loads, the "Open Modal" button should be visible.
  • Clicking the "Open Modal" button should make the Modal.vue appear.
  • The Card.vue component should be visible with its title and slot content.
  • Within the modal, a "Close" button (rendered by Button.vue) should be present.
  • Clicking the "Close" button inside the modal should make the modal disappear, and the "Open Modal" button should reappear.

Edge Cases:

  • Ensure proper prop types are defined for all components.
  • Handle the initial state of isModalOpen correctly (should be false).

Examples

Example 1: Initial App State

Input (Conceptual): The Vue application is initialized.

Output (Visual): A button labeled "Open Modal" is displayed. A card with a title (e.g., "Welcome") and some content (e.g., "This is a sample card.") is also displayed. The modal is not visible.

Explanation: App.vue renders its initial content, including the "Open Modal" button and the Card.vue component. The Modal.vue component is not rendered because isModalOpen is false.

Example 2: Opening the Modal

Input (Conceptual): The user clicks the "Open Modal" button in App.vue.

Output (Visual): The "Open Modal" button is still visible. A modal overlay appears on top of the other content. The modal has a title (e.g., "My Awesome Modal"), some content (if any is passed via slot), and a "Close" button.

Explanation: Clicking the "Open Modal" button in App.vue triggers a state change, setting isModalOpen to true. This causes the Modal.vue component to render.

Example 3: Closing the Modal

Input (Conceptual): The user clicks the "Close" button inside the opened modal.

Output (Visual): The modal overlay disappears. The "Open Modal" button and the card are again the primary visible elements.

Explanation: The Button.vue component inside Modal.vue emits a click event. App.vue listens for this close event (or any click event from the button within the modal, if you've designed it that way) and updates isModalOpen back to false, hiding the modal.

Constraints

  • Vue.js version: 3.x
  • Language: TypeScript
  • Component registration: Must use local registration (import and components option). Global registration is not permitted for this challenge.
  • Styling: Basic styling is sufficient. Focus on component structure and logic. No external CSS frameworks.
  • File structure: Organize components into a components directory (e.g., src/components/Button.vue, src/components/Card.vue, src/components/Modal.vue).

Notes

  • Remember to define prop types and emit events correctly using TypeScript.
  • When rendering the Modal.vue component in App.vue, you will need to pass the isOpen prop and bind to the close event.
  • Think about how to structure the Modal.vue to accept content from its parent using slots.
  • Consider using a simple conditional rendering (v-if or v-show) in Modal.vue based on the isOpen prop.
  • This challenge emphasizes the local registration pattern, so pay close attention to how you import and declare your components within App.vue.
Loading editor...
typescript