Vue.js course Β· Module 11: Pinia

Getters in Pinia

2 min read
In this lesson4

Getters are values computed based on state - like NOVA LAB analytical panels that process raw sensor data and present it in a readable form. They change automatically when the state changes.

Basic Getters

In Composition API, getters are simply computed():

1import { defineStore } from 'pinia'
2import { ref, computed } from 'vue'
3
4export const useInventoryStore = defineStore('inventory', () => {
5  const items = ref([
6    { name: 'Oxygen Tank', quantity: 12, category: 'life-support' },
7    { name: 'Water Filter', quantity: 5, category: 'life-support' },
8    { name: 'Solar Panel', quantity: 8, category: 'energy' },
9    { name: 'Drill Bit', quantity: 20, category: 'mining' }
10  ])
11
12  // Simple getter
13  const totalItems = computed(() =>
14    items.value.reduce((sum, item) => sum + item.quantity, 0)
15  )
16
17  // Filtering getter
18  const lifeSupportItems = computed(() =>
19    items.value.filter(item => item.category === 'life-support')
20  )
21
22  // Condition-checking getter
23  const hasShortage = computed(() =>
24    items.value.some(item => item.quantity < 3)
25  )
26
27  return { items, totalItems, lifeSupportItems, hasShortage }
28})

Getters Using Other Getters

Getters can be based on other getters:

1const lowStockItems = computed(() =>
2  items.value.filter(item => item.quantity < 5)
3)
4
5const lowStockCount = computed(() => lowStockItems.value.length)
6
7const stockStatus = computed(() => {
8  if (lowStockCount.value === 0) return 'OK'
9  if (lowStockCount.value <= 2) return 'WARNING'
10  return 'CRITICAL'
11})

Getters with Parameters

Computed doesn't accept arguments, but you can return a function:

1// Getter with parameter - returns a function
2const getItemsByCategory = computed(() => {
3  return (category) =>
4    items.value.filter(item => item.category === category)
5})
6
7const findItem = computed(() => {
8  return (name) =>
9    items.value.find(item =>
10      item.name.toLowerCase().includes(name.toLowerCase())
11    )
12})

Usage in a component:

1<template>
2  <div>
3    <p>Total: {{ store.totalItems }}</p>
4    <p>Status: {{ store.stockStatus }}</p>
5
6    <!-- Getter with parameter -->
7    <div v-for="item in store.getItemsByCategory('energy')" :key="item.name">
8      {{ item.name }}: {{ item.quantity }}
9    </div>
10  </div>
11</template>

Getters in storeToRefs

Getters (computed) are part of storeToRefs:

1<script setup>
2import { storeToRefs } from 'pinia'
3import { useInventoryStore } from '@/stores/inventory'
4
5const store = useInventoryStore()
6const { items, totalItems, hasShortage } = storeToRefs(store)
7</script>
Code for this lesson: App.vue
1<script setup>
2import { ref, computed } from 'vue'
3
4// Inventory Store simulation with getters
5const items = ref([
6  { name: 'Oxygen Tank', quantity: 12, category: 'life-support', unit: 'units' },
7  { name: 'Water Filter', quantity: 2, category: 'life-support', unit: 'units' },
8  { name: 'Solar Panel', quantity: 8, category: 'energy', unit: 'units' },
9  { name: 'Battery Pack', quantity: 15, category: 'energy', unit: 'units' },
10  { name: 'Drill Bit', quantity: 20, category: 'mining', unit: 'pcs' },
11  { name: 'Rock Sample Container', quantity: 1, category: 'mining', unit: 'units' }
12])
13
14const searchQuery = ref('')
15const selectedCategory = ref('all')
16
17// Getters
18const totalItems = computed(() =>
19  items.value.reduce((sum, item) => sum + item.quantity, 0)
20)
21
22const categories = computed(() =>
23  ['all', ...new Set(items.value.map(i => i.category))]
24)
25
26const filteredItems = computed(() => {
27  let result = items.value
28  if (selectedCategory.value !== 'all') {
29    result = result.filter(i => i.category === selectedCategory.value)
30  }
31  if (searchQuery.value) {
32    const q = searchQuery.value.toLowerCase()
33    result = result.filter(i => i.name.toLowerCase().includes(q))
34  }
35  return result
36})
37
38const lowStockItems = computed(() =>
39  items.value.filter(item => item.quantity < 5)
40)
41
42const stockStatus = computed(() => {
43  if (lowStockItems.value.length === 0) return 'OK'
44  if (lowStockItems.value.length <= 2) return 'WARNING'
45  return 'CRITICAL'
46})
47
48// Getter with a parameter
49const getByCategory = computed(() => {
50  return (cat) => items.value.filter(i => i.category === cat)
51})
52</script>
53
54<template>
55  <div class="nova-lab">
56    <h1>NOVA LAB - Inventory Getters</h1>
57
58    <div class="stats-bar">
59      <div class="stat-card">
60        <div class="stat-value">{{ totalItems }}</div>
61        <div class="stat-label">Total Items</div>
62      </div>
63      <div class="stat-card">
64        <div class="stat-value" :class="stockStatus.toLowerCase()">{{ stockStatus }}</div>
65        <div class="stat-label">Stock Status</div>
66      </div>
67      <div class="stat-card">
68        <div class="stat-value warning">{{ lowStockItems.length }}</div>
69        <div class="stat-label">Low Stock</div>
70      </div>
71    </div>
72
73    <div class="controls">
74      <input v-model="searchQuery" placeholder="Search..." class="search-input" />
75      <select v-model="selectedCategory" class="select">
76        <option v-for="cat in categories" :key="cat" :value="cat">
77          {{ cat === 'all' ? 'All Categories' : cat }}
78        </option>
79      </select>
80    </div>
81
82    <div class="inventory-grid">
83      <div v-for="item in filteredItems" :key="item.name"
84        class="item-card" :class="{ 'low-stock': item.quantity < 5 }">
85        <div class="item-name">{{ item.name }}</div>
86        <div class="item-qty">{{ item.quantity }} {{ item.unit }}</div>
87        <div class="item-cat">{{ item.category }}</div>
88      </div>
89    </div>
90
91    <div v-if="lowStockItems.length" class="alert-box">
92      Low stock: {{ lowStockItems.map(i => i.name).join(', ') }}
93    </div>
94  </div>
95</template>
96
97<style scoped>
98.nova-lab {
99  background: #0a0e27;
100  color: #00ff88;
101  min-height: 100vh;
102  padding: 20px;
103  font-family: monospace;
104}
105h1 { color: #00ff88; margin-bottom: 20px; text-align: center; }
106.stats-bar { display: flex; gap: 10px; margin-bottom: 15px; justify-content: center; }
107.stat-card {
108  background: rgba(0, 180, 216, 0.1);
109  border: 2px solid #00b4d8;
110  padding: 12px 20px;
111  text-align: center;
112}
113.stat-value { font-size: 1.4em; font-weight: bold; }
114.stat-label { color: #00b4d8; font-size: 0.8em; margin-top: 4px; }
115.ok { color: #00ff88; }
116.warning { color: #ff9900; }
117.critical { color: #ff4444; }
118.controls { display: flex; gap: 10px; margin-bottom: 15px; max-width: 500px; margin: 0 auto 15px; }
119.search-input, .select {
120  background: #0a0e27;
121  border: 2px solid #00b4d8;
122  color: #00ff88;
123  padding: 8px;
124  font-family: monospace;
125  flex: 1;
126}
127.inventory-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; }
128.item-card {
129  background: rgba(0, 255, 136, 0.05);
130  border: 2px solid #00ff88;
131  padding: 12px;
132}
133.item-card.low-stock { border-color: #ff4444; background: rgba(255, 68, 68, 0.1); }
134.item-name { font-weight: bold; margin-bottom: 5px; }
135.item-qty { color: #00b4d8; }
136.item-cat { color: #666; font-size: 0.85em; margin-top: 4px; }
137.alert-box {
138  margin-top: 15px;
139  padding: 10px;
140  background: rgba(255, 68, 68, 0.1);
141  border: 2px solid #ff4444;
142  color: #ff4444;
143}
144</style>

Spotted a mistake in this lesson?

Check yourself

Answer the questions from this lesson. Pick an answer to see right away whether it is correct.

  1. 1. What are getters in Pinia?

  2. 2. How are getters defined in a Composition API store?

These are 2 of 3 questions for this lesson. Solve the rest in the game.

Hands-on tasks in the game

  • Code editor

    Create getters in a Pinia store

  • Horizontal ordering

    Arrange the elements to define a getter in a Pinia store

  • Click in order

    Arrange the elements to create a getter with a parameter

  • Code editor

    Create getters that filter data based on parameters

Useful articles