Blog>
Snippets

State Management with Vuex-like Plugin

Illustrate how to build a simple state management plugin following the Vuex pattern, including a store, mutations, actions, and getters.
<!-- index.html -->
<div id='app'>
    <h1>{{ message }}</h1>
    <button @click='increment'>Increment</button>
    <p>Count is: {{ count }}</p>
</div>
This is the HTML structure with Vue binding and event handling. We have a message displayed, a button to increment the count, and a paragraph element that shows the current count.
/* styles.css */
#app {
    font-family: 'Arial', sans-serif;
}
h1 {
    color: #333;
}
CSS styles for the #app container and the h1 element, setting the font and color.
// store.js
const store = {
    state: {
        count: 0
    },
    mutations: {
        increment(state) {
            state.count++;
        }
    },
    actions: {
        increment(context) {
            context.commit('increment');
        }
    },
    getters: {
        count(state) {
            return state.count;
        }
    },
    commit(mutationKey, payload) {
        // call the specified mutation
        this.mutations[mutationKey](this.state, payload);
    },
    dispatch(actionKey, payload) {
        // call the specified action
        this.actions[actionKey]({ commit: this.commit.bind(this), state: this.state }, payload);
    }
};
This script defines a very simple Vuex-like store with state, mutations, actions, and getters. Mutations are used to synchronously change the state; actions are for asynchronous operations; getters for computed state values.
// main.js
const app = new Vue({
    el: '#app',
    data: function() {
        return {
            message: 'Simple Vuex-like State Management'
        }
    },
    computed: {
        count() {
            return store.getters.count(store.state);
        }
    },
    methods: {
        increment() {
            // Dispatch an action to increment the count
            store.dispatch('increment');
        }
    }
});
The main Vue instance is created here. It binds to the #app element and defines a data property for the message, a computed property for the count which uses the Vuex-like store getter, and a method to dispatch the increment action.