Global State Management with Vue and TypeScript
Managing application state effectively is crucial for complex Vue.js applications. This challenge focuses on implementing a simple global state management solution using Vue's reactivity system and TypeScript for type safety. You'll create a reusable GlobalState class that allows components to access and modify shared state across the application.
Problem Description
You are tasked with creating a GlobalState class in TypeScript that acts as a central repository for application-wide state. This class should:
- Hold State: Maintain a set of properties representing the global state. These properties should be reactive, meaning changes to them trigger updates in components that depend on them.
- Provide Accessors & Mutators: Offer methods to access and modify the state. Accessors should return the current value of a state property, and mutators should update the state property while ensuring reactivity.
- Be Reusable: The class should be designed to be easily instantiated with different initial state configurations.
- Type Safety: Utilize TypeScript to ensure type safety for the state properties and methods.
Expected Behavior:
- Components should be able to access the global state through the
GlobalStateinstance. - Modifying the state through the mutator methods should trigger updates in all components that are observing the state.
- The
GlobalStateclass should be flexible enough to handle different types of state properties (numbers, strings, booleans, objects, arrays).
Edge Cases to Consider:
- Handling initial state values correctly.
- Ensuring that state updates are reactive and trigger component re-renders.
- Preventing direct modification of the state properties to maintain control and reactivity.
Examples
Example 1:
Input:
GlobalState initialized with: { count: 0, message: "Hello" }
Component A: Displays count and message.
Component B: Displays count and message.
Component A calls: globalState.incrementCount()
Output:
Component A and Component B both update to display: count: 1, message: "Hello"
Explanation:
The `incrementCount()` method updates the `count` property in the `GlobalState` instance. Vue's reactivity system detects this change and re-renders both components that are observing the `count` property.
Example 2:
Input:
GlobalState initialized with: { user: { name: "Guest", loggedIn: false } }
Component A: Displays user.name and user.loggedIn.
Component B: Calls globalState.login("Alice")
Output:
Component A updates to display: user.name: "Alice", user.loggedIn: true
Explanation:
The `login()` method updates the `user` object within the `GlobalState`. Vue's reactivity system detects changes within nested objects and re-renders Component A.
Example 3:
Input:
GlobalState initialized with: { items: [] }
Component A: Calls globalState.addItem("Apple")
Output:
GlobalState.items becomes: ["Apple"]
Explanation:
The `addItem()` method adds a new item to the `items` array within the `GlobalState`. Vue's reactivity system detects changes to arrays and re-renders any components observing the `items` array.
Constraints
- Language: TypeScript
- Framework: Vue.js (using the reactivity system - no external state management libraries like Vuex or Pinia)
- Performance: The solution should be reasonably performant. Avoid unnecessary re-renders.
- State Size: Assume the global state will contain a moderate number of properties (less than 20).
- Mutability: Directly modifying the state properties (e.g.,
globalState.count = 5;) should not trigger reactivity. Use the provided mutator methods.
Notes
- Consider using Vue's
reactive()orref()functions to create reactive state properties within theGlobalStateclass. - Think about how to design the mutator methods to ensure they trigger reactivity when updating the state.
- Focus on creating a clean, reusable, and type-safe solution.
- You don't need to create a full-fledged Vue application. Just focus on the
GlobalStateclass itself and demonstrate its usage with simple examples. You can useconsole.logto simulate component updates for demonstration purposes.