Hone logo
Hone
Problems

Building Reusable Logic with Shared Composables in Vue

Sharing logic across components is a cornerstone of maintainable and efficient Vue applications. This challenge focuses on creating and utilizing shared composables – functions that encapsulate reusable logic – to avoid code duplication and improve component organization. You'll implement a composable that manages a counter and provides methods to increment, decrement, and reset it, then use this composable in multiple components.

Problem Description

You are tasked with creating a composable called useCounter that manages a counter value and provides methods for interacting with it. This composable should be designed to be easily reusable across different components within your Vue application. The composable should:

  1. Initialize: Start with a counter value of 0. It should accept an optional initial value as an argument.
  2. Increment: Provide a function increment that increases the counter by 1.
  3. Decrement: Provide a function decrement that decreases the counter by 1.
  4. Reset: Provide a function reset that sets the counter back to its initial value (0 if no initial value was provided).
  5. Return Value: Return an object containing the current counter value and the increment, decrement, and reset functions.

You will then create two Vue components, CounterComponentA and CounterComponentB, that each utilize the useCounter composable. CounterComponentA should display the counter value and provide buttons to increment and decrement it. CounterComponentB should display the counter value and provide a button to reset it. Changes to the counter in one component should be reflected in the other.

Examples

Example 1:

Input: Initial counter value = 5
CounterComponentA: Increment button pressed twice.
CounterComponentB: Displays the current counter value.
Output:
CounterComponentA: Counter value = 7
CounterComponentB: Counter value = 7
Explanation: The `useCounter` composable maintains a single counter state. Incrementing in CounterComponentA updates this shared state, which is then reflected in CounterComponentB.

Example 2:

Input: Initial counter value = 10
CounterComponentB: Reset button pressed.
CounterComponentA: Displays the current counter value.
Output:
CounterComponentA: Counter value = 0
CounterComponentB: Counter value = 0
Explanation: Resetting the counter in CounterComponentB updates the shared state, which is then reflected in CounterComponentA.

Example 3: (Edge Case)

Input: Initial counter value = -2
CounterComponentA: Decrement button pressed once.
CounterComponentB: Displays the current counter value.
Output:
CounterComponentA: Counter value = -3
CounterComponentB: Counter value = -3
Explanation: The counter can handle negative initial values and decrementing correctly.

Constraints

  • The useCounter composable must be implemented using Vue's Composition API (setup function).
  • The components CounterComponentA and CounterComponentB must be functional components.
  • The counter value should be reactive and changes should be reflected in both components.
  • The initial counter value passed to useCounter can be any number (positive, negative, or zero).
  • The code should be well-formatted and easy to understand.

Notes

  • Consider using ref from Vue to create a reactive counter value.
  • The useCounter composable should be designed to be generic and reusable in other parts of your application.
  • Focus on creating a clean and maintainable solution that demonstrates the benefits of using shared composables.
  • Think about how to handle the optional initial value argument in the useCounter composable.
Loading editor...
typescript