Vue JS State Management with Pinia/Vuex 2 — Questions and Answers
Question 1: In Pinia, how do you reset a store's state back to its initial values?
- store.$reset() (Correct answer)
- store.reset()
- store.$state = {}
- Pinia.resetAll()
Correct answer: store.$reset()
`$reset()` is a built-in Pinia method on Options Stores that restores state to the values returned by the `state` factory function.
`store.$reset()` is available on Pinia stores defined with the Options Store syntax. It calls the `state` factory function again and replaces the current state with fresh initial values. This is useful for logging out users, clearing forms, or resetting after navigation. Note: `$reset()` is NOT automatically available on Setup Stores because there's no state factory to call. For Setup Stores, you need to implement reset manually, e.g., by storing initial state and reassigning it.
Question 2: What is a Pinia plugin?
- A function added to the Pinia instance that can add properties or wrap actions for every store (Correct answer)
- A Vuex module compatible with Pinia
- A Vue component that reads from the store
- An npm package that extends Vue's reactivity
Correct answer: A function added to the Pinia instance that can add properties or wrap actions for every store
Pinia plugins are functions registered with `pinia.use(myPlugin)` that receive context for each store, allowing you to add shared properties, wrap actions, or persist state.
Pinia plugins are plain functions: `function myPlugin({ store, app, pinia, options }) { store.hello = 'world' }`. You register them with `pinia.use(myPlugin)`. The plugin runs for every store that is used after the plugin is registered. Common use cases include persisting state to localStorage (e.g., `pinia-plugin-persistedstate`), adding shared $id tracking, wrapping actions with error handling or logging, and integrating with authentication systems. Plugins can also add reactive state using `ref` inside them.
Question 3: How does Vuex handle asynchronous operations like API calls?
- Through actions, which can be async and then commit mutations (Correct answer)
- Through mutations, which support Promises
- Through async getters
- Through Vue's nextTick
Correct answer: Through actions, which can be async and then commit mutations
Vuex actions are the designated place for async logic. After the async work, the action commits a mutation to update state synchronously.
Vuex strictly separates synchronous state changes (mutations) from asynchronous operations (actions). An action receives a context object with `commit`, `state`, `getters`, and `dispatch` methods. A typical async action looks like: `async fetchUser({ commit }, id) { const user = await api.getUser(id); commit('SET_USER', user) }`. Actions return Promises, so you can chain them: `store.dispatch('fetchUser', id).then(...)`. In components, you call `store.dispatch('fetchUser', id)` to trigger the action.
Question 4: What is the difference between state and getters in Pinia?
- State holds raw reactive data; getters are computed properties derived from state (Correct answer)
- State is synchronous; getters are asynchronous
- Getters are writable; state is read-only
- There is no difference — they are aliases
Correct answer: State holds raw reactive data; getters are computed properties derived from state
State is the raw reactive data in a store, while getters are computed (memoized) values derived from state or other getters, similar to Vue's `computed` properties.
In Pinia's Options Store, `state` is a factory function returning the store's raw data: `state: () => ({ count: 0, todos: [] })`. `getters` are equivalent to Vue's `computed` properties — they derive values from state and are automatically memoized: `getters: { completedTodos: (state) => state.todos.filter(t => t.done) }`. In the Setup Store, `ref`/`reactive` = state, `computed` = getters, plain functions = actions. Getters update automatically when their dependencies change and are accessed directly: `store.completedTodos`.
Question 5: How do you subscribe to store mutations in Vuex 4?
- store.subscribe((mutation, state) => { ... }) (Correct answer)
- store.watch('mutation', callback)
- store.on('mutation', callback)
- store.addPlugin((mutation) => { ... })
Correct answer: store.subscribe((mutation, state) => { ... })
`store.subscribe` registers a handler called after every mutation, receiving the mutation object and resulting state. It returns an unsubscribe function.
`store.subscribe((mutation, state) => { ... })` registers a global mutation listener. The `mutation` argument has a `type` (mutation name) and `payload`. This is commonly used for state persistence (saving to localStorage after every change), analytics, or logging. The method returns a function to unsubscribe. For action subscriptions, use `store.subscribeAction`. Pinia's equivalent is `store.$onAction(({ name, args, after, onError }) => { ... })` for actions and `store.$subscribe((mutation, state) => { ... })` for state changes.
Question 6: In Vue 3 with Pinia, what does `$patch` do?
- Applies multiple state changes at once, either via an object or a function (Correct answer)
- Synchronizes the store with the server
- Resets the store to initial state
- Merges two stores into one
Correct answer: Applies multiple state changes at once, either via an object or a function
`$patch` allows applying multiple state mutations in a single operation, improving performance by batching reactivity updates.
`store.$patch({ count: 10, name: 'Alice' })` updates multiple state properties at once. Alternatively, `store.$patch((state) => { state.count++; state.items.push(newItem) })` accepts a mutator function for complex nested changes. Pinia batches all changes made inside a single `$patch` call into one reactive update, which is more efficient than modifying properties one by one. This is also useful when you need atomic updates where all changes should appear simultaneously in computed properties and watchers.
In Pinia, how do you reset a store's state back to its initial values?