Vue State Preservation Challenge: The Persistent Counter
This challenge focuses on implementing state preservation in a Vue.js application using TypeScript. You'll build a simple counter component whose current value persists even after the user navigates away from the page or refreshes the browser. This is a fundamental concept for creating more robust and user-friendly web applications.
Problem Description
Your task is to create a Vue.js component named PersistentCounter.vue that displays a numerical counter. The component should have two buttons: one to increment the counter and another to decrement it. The crucial requirement is that the counter's value must be preserved. When the user reloads the page or navigates to another page and then returns, the counter should display the last saved value.
Key Requirements:
- Vue Component: Create a Vue.js component using the Composition API and TypeScript.
- Counter Logic: Implement increment and decrement functionality for the counter.
- State Preservation: The counter's value must be persisted so it can be restored upon page reload or re-entry.
- User Interface: Display the current counter value and provide two buttons for interaction.
Expected Behavior:
- The component initializes with a counter value. If a previously saved value exists, it should be loaded. Otherwise, it should default to 0.
- Clicking the "Increment" button increases the counter by 1.
- Clicking the "Decrement" button decreases the counter by 1.
- Upon any change to the counter's value, the new value should be automatically saved.
- When the page is reloaded or the user revisits the application after closing it, the last saved counter value should be displayed.
Edge Cases to Consider:
- Initial Load: What happens when the application is loaded for the first time and no state has been saved?
- Invalid Saved Data: Although not strictly required for this basic version, consider how you might handle corrupted or invalid saved data (e.g., if the stored value is not a number). For this challenge, you can assume valid numeric data will be stored.
Examples
Example 1:
- Scenario: User opens the application for the first time.
- Input: N/A (initial state)
- Output:
- Counter Display:
0 - Buttons:
Increment,Decrement
- Counter Display:
- Explanation: Since no state is saved, the counter defaults to 0.
Example 2:
- Scenario: User increments the counter to 5, then reloads the page.
- Input: State was previously saved with value
5. - Output:
- Counter Display:
5 - Buttons:
Increment,Decrement
- Counter Display:
- Explanation: The application loads the previously saved value of 5.
Example 3:
- Scenario: User increments to 3, decrements to 1, then reloads.
- Input: State was previously saved with value
1. - Output:
- Counter Display:
1 - Buttons:
Increment,Decrement
- Counter Display:
- Explanation: The latest saved value, 1, is restored.
Constraints
- The state preservation mechanism should use the browser's
localStorageAPI. - The counter value will always be an integer.
- The counter value will not exceed
Number.MAX_SAFE_INTEGERor go belowNumber.MIN_SAFE_INTEGER. - The implementation should be written entirely in TypeScript.
- The solution should be a single
.vuefile component.
Notes
- Consider using Vue's
refandwatchreactivity primitives for managing and reacting to state changes. - When saving to
localStorage, remember that it only stores strings. You'll need to handle serialization and deserialization. - Think about when the
localStoragesetItemoperation should occur to ensure the most up-to-date state is saved. - A good approach would be to load the state when the component is created and save it whenever the counter's value changes.