Vue Action Subscribers: Building Responsive UI Components
This challenge focuses on creating reusable and reactive UI components in Vue.js using TypeScript. You'll learn how to implement "action subscribers" – components that react to specific events or changes emitted by a parent component, allowing for decoupled and flexible application architecture.
Problem Description
Your task is to build a parent component and several child components that demonstrate the concept of action subscribers. The parent component will emit custom events, and the child components will listen for these events and update their UI accordingly. This pattern is useful for scenarios where a central component needs to trigger actions or display information in multiple, independent parts of the UI.
Key Requirements:
-
Parent Component (
EventEmitterComponent):- Should have a button that, when clicked, emits a custom event.
- The emitted event should carry a payload (e.g., a string message or an object).
- The parent component should manage the state that determines which event is emitted or what data is sent with the event.
-
Child Components (e.g.,
MessageDisplayComponent,StatusIndicatorComponent):- Each child component should be designed to "subscribe" to specific events emitted by the
EventEmitterComponent. - When a subscribed event is received, the child component should update its local state and render a corresponding UI element.
- Child components should be reusable and not tightly coupled to the specific implementation of the parent's event triggering logic, only to the event names and expected payloads.
- Each child component should be designed to "subscribe" to specific events emitted by the
-
TypeScript Integration:
- All components and their props/events should be defined using TypeScript, ensuring type safety.
- Use Vue's Composition API for component logic.
Expected Behavior:
- When the button in
EventEmitterComponentis clicked, it emits an event. MessageDisplayComponentlistens for a "displayMessage" event and shows the message payload.StatusIndicatorComponentlistens for a "updateStatus" event and displays a status indicator (e.g., text or color) based on the payload.- Multiple instances of child components can exist and each should independently react to the events.
Edge Cases to Consider:
- What happens if a child component is not mounted when an event is emitted? (Vue handles this gracefully, but it's good to be aware).
- How can you ensure type safety for the event payloads?
Examples
Example 1: Basic Event Emission and Subscription
Input: (Conceptual - based on user interaction with the UI)
Parent Button Clicked -> Emits "displayMessage" with payload: "Hello World!"
Output:
MessageDisplayComponent displays: "Message: Hello World!"
Example 2: Different Event and Payload
Input: (Conceptual)
Parent Button Clicked -> Emits "updateStatus" with payload: { status: "active", color: "green" }
Output:
StatusIndicatorComponent displays: A green indicator with text "Status: active"
Example 3: Multiple Subscribers
Input: (Conceptual)
Parent Button Clicked -> Emits "displayMessage" with payload: "System Update"
Parent Button Clicked Again -> Emits "updateStatus" with payload: { status: "pending", color: "orange" }
Output:
MessageDisplayComponent displays: "Message: System Update"
StatusIndicatorComponent displays: An orange indicator with text "Status: pending"
Constraints
- Vue.js version 3.x with Composition API.
- TypeScript 4.x or later.
- Solution should be a single Vue SFC (Single File Component) structure for demonstration, or clearly defined separate components if preferred.
- No external state management libraries (like Pinia or Vuex) should be used for this specific challenge. Event emission and listening should be handled directly between parent and child.
- Component names should follow PascalCase convention.
Notes
- Think about how
emitworks in Vue's Composition API (setupfunction). - Consider using
defineEmitsfor robust event handling and type safety. definePropswill be crucial for defining the interface of your child components, although in this specific challenge, their interaction is primarily event-driven.- The core of this challenge is understanding the parent-child communication via custom events and how to make child components react to these events.
- You might want to simulate different event types being emitted from the parent to showcase the flexibility of the subscriber pattern.