0
# Composition API
1
2
Vue 3 Composition API integration for accessing Vuex stores in components with full type safety.
3
4
## Capabilities
5
6
### Store Access Hook
7
8
Access the Vuex store instance within Vue 3 composition functions.
9
10
```typescript { .api }
11
/**
12
* Access the Vuex store instance in composition functions
13
* @param injectKey - Optional custom injection key
14
* @returns Store instance
15
*/
16
function useStore<S = any>(injectKey?: InjectionKey<Store<S>> | string): Store<S>;
17
```
18
19
**Usage Examples:**
20
21
```typescript
22
import { computed } from 'vue';
23
import { useStore } from 'vuex';
24
25
export default {
26
setup() {
27
const store = useStore();
28
29
// Access state reactively
30
const count = computed(() => store.state.count);
31
const user = computed(() => store.state.user);
32
33
// Access getters
34
const isLoggedIn = computed(() => store.getters.isLoggedIn);
35
const cartTotal = computed(() => store.getters['cart/total']);
36
37
// Create action functions
38
const increment = () => store.commit('increment');
39
const login = (credentials) => store.dispatch('login', credentials);
40
41
return {
42
count,
43
user,
44
isLoggedIn,
45
cartTotal,
46
increment,
47
login
48
};
49
}
50
};
51
```
52
53
### Custom Injection Key
54
55
Use a custom injection key for type safety and multiple store instances.
56
57
```typescript { .api }
58
/**
59
* Default injection key for store
60
*/
61
const storeKey: string;
62
```
63
64
**Usage Examples:**
65
66
```typescript
67
import { InjectionKey } from 'vue';
68
import { createStore, Store, useStore } from 'vuex';
69
70
// Define state interface
71
interface State {
72
count: number;
73
user: User | null;
74
}
75
76
// Create typed injection key
77
const key: InjectionKey<Store<State>> = Symbol();
78
79
// Create store with typed key
80
const store = createStore<State>({
81
state: {
82
count: 0,
83
user: null
84
}
85
});
86
87
// Install with custom key
88
app.use(store, key);
89
90
// Use with custom key for type safety
91
export default {
92
setup() {
93
const store = useStore(key); // Fully typed as Store<State>
94
95
const count = computed(() => store.state.count); // count is number
96
const user = computed(() => store.state.user); // user is User | null
97
98
return { count, user };
99
}
100
};
101
```
102
103
### Multiple Store Instances
104
105
Access different store instances using different injection keys.
106
107
**Usage Examples:**
108
109
```typescript
110
import { InjectionKey } from 'vue';
111
import { Store, useStore } from 'vuex';
112
113
// Define different store types
114
interface MainState { /* ... */ }
115
interface CacheState { /* ... */ }
116
117
// Create keys for different stores
118
const mainStoreKey: InjectionKey<Store<MainState>> = Symbol('main');
119
const cacheStoreKey: InjectionKey<Store<CacheState>> = Symbol('cache');
120
121
export default {
122
setup() {
123
// Access different stores
124
const mainStore = useStore(mainStoreKey);
125
const cacheStore = useStore(cacheStoreKey);
126
127
const mainData = computed(() => mainStore.state.data);
128
const cacheData = computed(() => cacheStore.state.cache);
129
130
const refreshData = async () => {
131
await mainStore.dispatch('fetchData');
132
cacheStore.commit('clearCache');
133
};
134
135
return { mainData, cacheData, refreshData };
136
}
137
};
138
```
139
140
### Composable Functions
141
142
Create reusable composable functions that encapsulate store logic.
143
144
**Usage Examples:**
145
146
```typescript
147
import { computed } from 'vue';
148
import { useStore } from 'vuex';
149
150
// User management composable
151
export function useUser() {
152
const store = useStore();
153
154
const user = computed(() => store.state.user);
155
const isLoggedIn = computed(() => store.getters.isLoggedIn);
156
157
const login = async (credentials) => {
158
return await store.dispatch('login', credentials);
159
};
160
161
const logout = () => {
162
store.commit('logout');
163
};
164
165
return {
166
user,
167
isLoggedIn,
168
login,
169
logout
170
};
171
}
172
173
// Cart management composable
174
export function useCart() {
175
const store = useStore();
176
177
const items = computed(() => store.state.cart.items);
178
const total = computed(() => store.getters['cart/total']);
179
const itemCount = computed(() => store.getters['cart/itemCount']);
180
181
const addItem = (item) => {
182
store.commit('cart/addItem', item);
183
};
184
185
const removeItem = (itemId) => {
186
store.commit('cart/removeItem', itemId);
187
};
188
189
const clearCart = () => {
190
store.commit('cart/clear');
191
};
192
193
return {
194
items,
195
total,
196
itemCount,
197
addItem,
198
removeItem,
199
clearCart
200
};
201
}
202
203
// Using composables in components
204
export default {
205
setup() {
206
const { user, isLoggedIn, login, logout } = useUser();
207
const { items, total, addItem } = useCart();
208
209
return {
210
user,
211
isLoggedIn,
212
login,
213
logout,
214
cartItems: items,
215
cartTotal: total,
216
addToCart: addItem
217
};
218
}
219
};
220
```
221
222
### Reactive State Watching
223
224
Watch store state changes using Vue's reactive system.
225
226
**Usage Examples:**
227
228
```typescript
229
import { watch, watchEffect } from 'vue';
230
import { useStore } from 'vuex';
231
232
export default {
233
setup() {
234
const store = useStore();
235
236
// Watch specific state changes
237
watch(
238
() => store.state.user,
239
(newUser, oldUser) => {
240
console.log('User changed:', { newUser, oldUser });
241
},
242
{ deep: true }
243
);
244
245
// Watch getters
246
watch(
247
() => store.getters.isLoggedIn,
248
(isLoggedIn) => {
249
if (isLoggedIn) {
250
// Redirect to dashboard
251
router.push('/dashboard');
252
}
253
}
254
);
255
256
// Watch multiple values
257
watchEffect(() => {
258
const count = store.state.count;
259
const user = store.state.user;
260
261
console.log(`Count: ${count}, User: ${user?.name}`);
262
});
263
264
// Watch with cleanup
265
const stopWatcher = watch(
266
() => store.state.notifications,
267
(notifications) => {
268
notifications.forEach(showNotification);
269
}
270
);
271
272
// Cleanup on unmount
273
onUnmounted(() => {
274
stopWatcher();
275
});
276
}
277
};
278
```