Defining a Store
Pinia stores are defined with defineStore. The setup syntax — using the Composition API inside a store — is the modern, recommended style and the one FamilyTree uses.
Installing Pinia
Section titled “Installing Pinia”If you scaffolded with create-vue and selected Pinia, it’s already installed and added to main.ts:
import { createApp } from 'vue'import { createPinia } from 'pinia'import App from './App.vue'
const app = createApp(App)app.use(createPinia()) // install Pinia before mountingapp.mount('#app')If you need to add it manually: npm install pinia.
Defining a store with setup syntax
Section titled “Defining a store with setup syntax”import { ref, computed } from 'vue'import { defineStore } from 'pinia'
export const useFamilyStore = defineStore('family', () => { // state const people = ref([]) const focusPersonId = ref(null)
// getters (computed) const focusPerson = computed(() => people.value.find(p => p.id === focusPersonId.value) )
// actions (functions) function setFocus(id) { focusPersonId.value = id }
return { people, focusPersonId, focusPerson, setFocus }})The setup syntax is exactly like writing a composable:
ref()creates reactive statecomputed()creates derived getters- Regular functions are actions
- Everything returned is available to components
The naming convention
Section titled “The naming convention”Pinia store IDs use kebab-case strings: 'family', 'user-settings', 'cart'. The composable function uses use + store name + Store: useFamilyStore, useCartStore.
export const useFamilyStore = defineStore('family', () => { ... })
// src/stores/userStore.tsexport const useUserStore = defineStore('user', () => { ... })Where to define stores
Section titled “Where to define stores”Store files live in src/stores/. Each store is a separate file. FamilyTree only needs one store — familyStore.ts — because all state is closely related.
The store ID
Section titled “The store ID”The first argument to defineStore ('family') is the store’s ID — a unique string used internally by Pinia for dev tools, persistence, and SSR. It must be unique across all stores.
Exercise
Section titled “Exercise”- Create
src/stores/counterStore.tswith acountref, anincrementaction, and adoubledcomputed. - Export it as
useCounterStore. - In a component, import
useCounterStore, call it, and displaystore.countandstore.doubled. - Add a button that calls
store.increment()and verify both values update.
defineStore('id', setup)creates a Pinia store using the Composition API inside the setup function.ref()= state,computed()= getters, functions = actions — same patterns as component setup.- Store composables follow the
use[Name]Storeconvention. - Install Pinia with
app.use(createPinia())beforeapp.mount(). - Everything the setup function returns is accessible on the store instance.