State management pattern and library for Vue.js applications that serves as a centralized store with predictable state mutations
—
Vue 3 Composition API integration for accessing Vuex stores in components with full type safety.
Access the Vuex store instance within Vue 3 composition functions.
/**
* Access the Vuex store instance in composition functions
* @param injectKey - Optional custom injection key
* @returns Store instance
*/
function useStore<S = any>(injectKey?: InjectionKey<Store<S>> | string): Store<S>;Usage Examples:
import { computed } from 'vue';
import { useStore } from 'vuex';
export default {
setup() {
const store = useStore();
// Access state reactively
const count = computed(() => store.state.count);
const user = computed(() => store.state.user);
// Access getters
const isLoggedIn = computed(() => store.getters.isLoggedIn);
const cartTotal = computed(() => store.getters['cart/total']);
// Create action functions
const increment = () => store.commit('increment');
const login = (credentials) => store.dispatch('login', credentials);
return {
count,
user,
isLoggedIn,
cartTotal,
increment,
login
};
}
};Use a custom injection key for type safety and multiple store instances.
/**
* Default injection key for store
*/
const storeKey: string;Usage Examples:
import { InjectionKey } from 'vue';
import { createStore, Store, useStore } from 'vuex';
// Define state interface
interface State {
count: number;
user: User | null;
}
// Create typed injection key
const key: InjectionKey<Store<State>> = Symbol();
// Create store with typed key
const store = createStore<State>({
state: {
count: 0,
user: null
}
});
// Install with custom key
app.use(store, key);
// Use with custom key for type safety
export default {
setup() {
const store = useStore(key); // Fully typed as Store<State>
const count = computed(() => store.state.count); // count is number
const user = computed(() => store.state.user); // user is User | null
return { count, user };
}
};Access different store instances using different injection keys.
Usage Examples:
import { InjectionKey } from 'vue';
import { Store, useStore } from 'vuex';
// Define different store types
interface MainState { /* ... */ }
interface CacheState { /* ... */ }
// Create keys for different stores
const mainStoreKey: InjectionKey<Store<MainState>> = Symbol('main');
const cacheStoreKey: InjectionKey<Store<CacheState>> = Symbol('cache');
export default {
setup() {
// Access different stores
const mainStore = useStore(mainStoreKey);
const cacheStore = useStore(cacheStoreKey);
const mainData = computed(() => mainStore.state.data);
const cacheData = computed(() => cacheStore.state.cache);
const refreshData = async () => {
await mainStore.dispatch('fetchData');
cacheStore.commit('clearCache');
};
return { mainData, cacheData, refreshData };
}
};Create reusable composable functions that encapsulate store logic.
Usage Examples:
import { computed } from 'vue';
import { useStore } from 'vuex';
// User management composable
export function useUser() {
const store = useStore();
const user = computed(() => store.state.user);
const isLoggedIn = computed(() => store.getters.isLoggedIn);
const login = async (credentials) => {
return await store.dispatch('login', credentials);
};
const logout = () => {
store.commit('logout');
};
return {
user,
isLoggedIn,
login,
logout
};
}
// Cart management composable
export function useCart() {
const store = useStore();
const items = computed(() => store.state.cart.items);
const total = computed(() => store.getters['cart/total']);
const itemCount = computed(() => store.getters['cart/itemCount']);
const addItem = (item) => {
store.commit('cart/addItem', item);
};
const removeItem = (itemId) => {
store.commit('cart/removeItem', itemId);
};
const clearCart = () => {
store.commit('cart/clear');
};
return {
items,
total,
itemCount,
addItem,
removeItem,
clearCart
};
}
// Using composables in components
export default {
setup() {
const { user, isLoggedIn, login, logout } = useUser();
const { items, total, addItem } = useCart();
return {
user,
isLoggedIn,
login,
logout,
cartItems: items,
cartTotal: total,
addToCart: addItem
};
}
};Watch store state changes using Vue's reactive system.
Usage Examples:
import { watch, watchEffect } from 'vue';
import { useStore } from 'vuex';
export default {
setup() {
const store = useStore();
// Watch specific state changes
watch(
() => store.state.user,
(newUser, oldUser) => {
console.log('User changed:', { newUser, oldUser });
},
{ deep: true }
);
// Watch getters
watch(
() => store.getters.isLoggedIn,
(isLoggedIn) => {
if (isLoggedIn) {
// Redirect to dashboard
router.push('/dashboard');
}
}
);
// Watch multiple values
watchEffect(() => {
const count = store.state.count;
const user = store.state.user;
console.log(`Count: ${count}, User: ${user?.name}`);
});
// Watch with cleanup
const stopWatcher = watch(
() => store.state.notifications,
(notifications) => {
notifications.forEach(showNotification);
}
);
// Cleanup on unmount
onUnmounted(() => {
stopWatcher();
});
}
};Install with Tessl CLI
npx tessl i tessl/npm-vuex