Vue 3 Composition API Counter Component
Create a reusable Vue 3 component using the Composition API and TypeScript that displays a counter and allows users to increment or decrement its value. This challenge will test your understanding of setup function, ref, and basic event handling in Vue 3.
Problem Description
You need to build a CounterComponent that:
- Displays a counter value: Initially, the counter should start at 0.
- Provides increment and decrement buttons: Two buttons should be present, one to increase the counter value by 1 and another to decrease it by 1.
- Uses Vue 3 Composition API: The component's logic must be implemented within the
setupfunction. - Utilizes TypeScript: All logic and types should be defined using TypeScript.
- Is reusable: The component should be designed in a way that it can be used multiple times within an application with independent counter states.
Key Requirements:
- The counter value should be reactive.
- The component should emit an event whenever the counter value changes.
- The initial value of the counter should be customizable via a prop.
Expected Behavior:
When the "Increment" button is clicked, the displayed number increases by 1.
When the "Decrement" button is clicked, the displayed number decreases by 1.
The component should display the current value of the counter.
When the initialValue prop is provided, the counter should start with that value.
An event named valueChanged should be emitted with the new counter value as its payload whenever the counter is incremented or decremented.
Edge Cases to Consider:
- What happens if the
initialValueprop is not a number? (While not strictly required to handle invalid prop types for this challenge, it's good to be aware). - Consider potential for very large or very small numbers (though for this challenge, standard number limits are acceptable).
Examples
Example 1:
Input (Vue Template Usage):
<CounterComponent :initialValue="5" @valueChanged="handleValueChange"/>
Expected Output (Initial Render):
A UI displaying:
- The number
5. - An "Increment" button.
- A "Decrement" button.
After clicking "Increment" once:
A UI displaying:
- The number
6. - The event
valueChangedis emitted with payload6.
After clicking "Decrement" once (from initial state):
A UI displaying:
- The number
4. - The event
valueChangedis emitted with payload4.
Example 2:
Input (Vue Template Usage):
<CounterComponent @valueChanged="logChange"/>
Expected Output (Initial Render):
A UI displaying:
- The number
0. - An "Increment" button.
- A "Decrement" button.
After clicking "Increment" three times:
A UI displaying:
- The number
3. - The event
valueChangedis emitted three times, with payloads1,2, and3respectively.
Constraints
- The
initialValueprop should be an optional number. If not provided, it defaults to 0. - The component should be a functional component (though a standard SFC is also acceptable for demonstrating
setup). - The solution should strictly adhere to the Vue 3 Composition API and TypeScript.
Notes
- Remember to import
reffromvue. - The
setupfunction returns an object whose properties are exposed to the component's template. - You'll need to define props and emit events using the
definePropsanddefineEmitshelper functions available in<script setup>. If not using<script setup>, you'll usepropsandemitarguments in thesetupfunction. - Think about how to make the counter value reactive.
- Consider how to bind click events to your buttons.