Why use Vuex
- The general advice is don't use Vuex until you think you need it
- If you think Vuex is too heavy for your needs, try store pattern
- Vuex is a centralize storage, meaning multiple components can access the same storage, and it could be accessed outside of components as well
- Vuex consist of state (the data), getters (computed state), mutations (function to modify the state) and actions (async functions to fetch data and commit mutations).
My use case for Vuex is I was building a SPA with multiple pages of content with SSR as well based on this sample.
- Vuex is useful to preload the data/state before the component is rendered
- When I am switching pages/components, I can reuse the data/state as cache to avoid fetching data from server again
Actions
is nice as a repository of code how the data/state is filled, decouple the fetch code from components.
Setup
Install
npm install vuex --save
Setup
import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)
Usage
import store from './store'const app = new Vue({ // router, // optional store, // to allow this.$store access in component render: h => h(App)})
Create
Create src/store/index.js
.
import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({ state: { count: 0, home: null, homePages: {} }, mutations: { increment (state) { state.count++ }, setHome(state, data) { state.home = data }, setHomePage(state, { id, data }) { Vue.set(state.homePages, id, data) } }, actions: { fetchFileHashes({ commit, state }) { return new Promise((resolve, reject) => { if (!state.fileHashes) { fetch('/data/hash.json', {cache: 'no-cache'}).then(response => response.json()).then(data => { commit('setFileHashes', data) resolve(data) }) } else { resolve(state.fileHashes) } }) }, // example via callback fetchHome({ commit }) { fetch('/data/home.json').then(response => response.json()).then(data => { commit('setHome', data) }) }, // example via async async fetchHomePage({ dispatch, commit, state }, id) { const response = await fetch(`/data/page-${id}.json`) const data = await response.json() commit('setHomePage', {id, data}) } }})export default store
You can update store from outside of component.
import store from './store'store.commit('increment')const count = store.state.count
Components
Call vuex in components
export default { computed: { home() { return this.$store.state.home }, homePage1() { return this.$store.state.homePages[1] } count() { return this.$store.state.count } }, created() { this.$store.commit('increment') // commit for mutation this.$store.dispatch('fetchHome') // dispatch for action this.$store.dispatch('fetchHomePage', 1) }}