Embark on a journey of knowledge! Take the quiz and earn valuable credits.
Take A QuizChallenge yourself and boost your learning! Start the quiz now to earn credits.
Take A QuizUnlock your potential! Begin the quiz, answer questions, and accumulate credits along the way.
Take A Quiz
🧭 What You’ll Learn
By the end of this chapter, you’ll be able to:
🧠 What Is State
Management?
In a Vue.js application, "state" refers to
the data that your components rely on: user input, fetched data, UI flags, etc.
When apps grow, managing state becomes difficult because:
This is where a centralized store comes in—Pinia
and Vuex are tools that help manage this shared data in a predictable,
scalable way.
📦 Common Use Cases for a
Global Store
Use Case |
Example |
Authentication |
Current user info across
pages |
Cart data |
Add/remove
items from anywhere |
Theme settings |
Toggle light/dark
globally |
App-wide notifications |
Trigger
toasts/alerts |
Persistent form
data |
Store data during
multi-step wizards |
🧩 Pinia vs. Vuex: What's
the Difference?
Feature |
Pinia |
Vuex |
Vue version |
Vue 3 (official
replacement) |
Vue 2/3 |
API Style |
Composition
API |
Options API |
Setup required |
Minimal |
Verbose |
Learning curve |
Easy |
Moderate |
Dev tools |
Yes (integrates with
Vue DevTools) |
Yes |
Bundle size |
Smaller |
Larger |
TL;DR: Use Pinia for Vue 3. Use Vuex
only for legacy Vue 2 apps or if already integrated.
⚡ Getting Started with Pinia (Vue
3)
✅ Step 1: Install Pinia
bash
npm
install pinia
✅ Step 2: Register Pinia in
main.js
js
import
{ createApp } from 'vue'
import
App from './App.vue'
import
{ createPinia } from 'pinia'
const
app = createApp(App)
app.use(createPinia())
app.mount('#app')
✅ Step 3: Create a Store
Create src/stores/counter.js:
js
import
{ defineStore } from 'pinia'
export
const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
getters: {
doubleCount: (state) => state.count * 2
},
actions: {
increment() {
this.count++
},
reset() {
this.count = 0
}
}
})
✅ Step 4: Use the Store in
Components
Example: Counter.vue
vue
<script
setup>
import
{ useCounterStore } from '../stores/counter'
const
counter = useCounterStore()
</script>
<template>
<div>
<p>Count: {{ counter.count
}}</p>
<p>Double: {{ counter.doubleCount
}}</p>
<button
@click="counter.increment">+</button>
<button
@click="counter.reset">Reset</button>
</div>
</template>
🧠 What Makes Pinia
Developer-Friendly?
🔒 Vuex Overview (Vue
2/Legacy Projects)
✅ Step 1: Install Vuex
bash
npm
install vuex@next
✅ Step 2: Create a Vuex Store
js
//
store/index.js
import
{ createStore } from 'vuex'
const
store = createStore({
state: {
count: 0
},
getters: {
doubleCount: (state) => state.count * 2
},
mutations: {
increment(state) {
state.count++
},
reset(state) {
state.count = 0
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment')
}, 500)
}
}
})
export default store
✅ Step 3: Register in main.js
js
import
store from './store'
createApp(App).use(store).mount('#app')
✅ Step 4: Use Store in Components
vue
<template>
<div>
<p>Count: {{ $store.state.count
}}</p>
<button
@click="$store.commit('increment')">+</button>
<button
@click="$store.dispatch('incrementAsync')">Async +</button>
</div>
</template>
🎨 Pinia vs Vuex API
Comparison
Feature |
Pinia Example |
Vuex Example |
State |
store.count |
$store.state.count |
Getter |
store.doubleCount |
$store.getters.doubleCount |
Mutation/Action |
store.increment() |
$store.commit('increment') |
Registration |
defineStore() |
createStore() |
DevTool Tabs |
“Pinia” tab |
“Vuex” tab |
📁 Suggested Store File
Organization (Pinia)
bash
src/
├── stores/
│ ├──
counter.js
│ ├── auth.js
│ └── theme.js
Each file represents a separate domain module,
keeping things modular and testable.
🔁 Sharing State Across
Components
You can use the same store instance in multiple components:
vue
<script
setup>
import
{ useCounterStore } from '@/stores/counter'
const
counter = useCounterStore()
</script>
<template>
<p>The count is {{ counter.count
}}</p>
</template>
If one component updates the state, all other components reactively
reflect that change.
🧠 Best Practices
🧪 Example: Auth Store
with Async Action
js
export
const useAuthStore = defineStore('auth', {
state: () => ({
user: null,
loading: false
}),
actions: {
async login(email, password) {
this.loading = true
const response = await
fetch('/api/login', {
method: 'POST',
body: JSON.stringify({ email, password
})
})
const data = await response.json()
this.user = data.user
this.loading = false
},
logout() {
this.user = null
}
}
})
🧪 Testing Pinia Stores
Testing Pinia is straightforward:
js
import
{ setActivePinia, createPinia } from 'pinia'
import
{ useCounterStore } from '@/stores/counter'
beforeEach(()
=> {
setActivePinia(createPinia())
})
test('increment
counter', () => {
const counter = useCounterStore()
counter.increment()
expect(counter.count).toBe(1)
})
✅ Recap: When to Use a Store
Situation |
Use Pinia/Vuex? |
Passing data across
pages |
✅ |
Deeply nested components |
✅ |
Local state
(checkbox toggle) |
❌ |
Shared UI behavior |
✅
(optional) |
API result caching |
✅ |
Answer:
A Single Page Application is a web app that loads a single HTML file and
dynamically updates the content without refreshing the page. This allows for a
smoother user experience, similar to desktop or mobile apps.
Answer:
Vue.js is lightweight, beginner-friendly, and has a powerful ecosystem. It
supports component-based architecture and works seamlessly with Vue Router for
SPA navigation. It’s a great choice for fast, reactive, and scalable SPAs.
Answer:
Answer:
Vue Router handles navigation in the browser without reloading pages. It maps
URL paths to Vue components and updates the view dynamically using the
browser’s History API.
Answer:
Technically yes, but it’s not recommended. Vue Router provides essential SPA
features like URL mapping, history handling, navigation guards, and lazy
loading.
Answer:
Both are state management libraries. Vuex is the older, more complex
option, while Pinia is the official replacement for Vue 3—lighter,
easier to use, and modular.
Answer:
Yes, but it's only suitable for small-scale SPAs. For larger projects, using
the Vue CLI or Vite offers better file organization, hot reloading, and tooling
support.
Answer:
SPAs typically have poor SEO out of the box because content is rendered via
JavaScript. Use pre-rendering (e.g., with Prerender.io) or switch to Server-Side Rendering (SSR) with
Nuxt.js for better SEO.
Answer:
You can deploy your Vue SPA on:
Answer:
Yes. Vue.js is modular and scalable. With features like lazy loading, component
splitting, Pinia/Vuex for state management, and Vue Router, it can power large,
production-ready SPAs effectively.
Please log in to access this content. You will be redirected to the login page shortly.
LoginReady to take your education and career to the next level? Register today and join our growing community of learners and professionals.
Comments(0)