Search code examples
javascriptvue.jsvuex

Vuex - Create global method to dispatch action


Where can I put a global method that dispatches a Vuex action? I created a Vuex module "simplert" that has some functions to show simplert. I have created an HTML file where I put my single simplert

<simplert :use-radius="true"
              :use-icon="true"
              ref="simplert">
</simplert>

I use it to show through the store module's functions some simple messages (info, warning, error etc.). This is my module:

/* eslint-disable no-shadow */
/**
 * Vuex Module to control the component Simplert
 */
import { trans } from '../../plugin/translation';

// initial state
function initialState() {
    return {
        title: '',
        message: '',
        type: 'info',
        customClass: 'simplert-popup',
        customIconUrl: '',
        customCloseBtnText: trans('close'),
        customCloseBtnClass: 'btn btn-primary',
        useConfirmBtn: false,
        customConfirmBtnText: trans('confirm'),
        customConfirmBtnClass: 'btn btn-success',
        disableOverlayClick: '',
        hideAllButton: false,
        showXclose: true,
        onOpen: null,
        onConfirm: null,
        onClose: null,
    };
}

// state
const state = initialState();

// mutations
const mutations = {
    show(state, simplert) {
        simplert.openSimplert(state);
    },
    reset(state) {
        const s = initialState();
        Object.keys(s).forEach((key) => {
            state[key] = s[key];
        });
    },
    setData(state, data) {
        Object.keys(data).forEach((key) => {
            state[key] = data[key];
        });
    },
};

// actions
const actions = {
    reset({ commit }) {
        return new Promise((resolve) => {
            commit('reset');
            resolve();
        });
    },
    show({ dispatch, commit }, { alert, data }) {
        dispatch('reset').then(() => {
            commit('setData', data);
            commit('show', alert);
        });
    },
    showInfoAlert({ dispatch }, { alert, title, message }) {
        const data = {
            title,
            message,
            type: 'info',
        };

        dispatch('show', { alert, data });
    },
    showSuccessAlert({ dispatch }, { alert, title, message }) {
        const data = {
            title,
            message,
            type: 'success',
        };

        dispatch('show', { alert, data });
    },
    showErrorAlert({ dispatch }, { alert, title, message }) {
        const data = {
            title,
            message,
            type: 'error',
        };

        dispatch('show', { alert, data });
    },
    showWarningAlert({ dispatch }, { alert, title, message }) {
        const data = {
            title,
            message,
            type: 'warning',
        };

        dispatch('show', { alert, data });
    },
};

export default {
    namespaced: true,
    state,
    mutations,
    actions,
};

Now I want to create a global method that uses the "showErrorAlert" action to display the errors that come from Promise. So to dispatch the action I use this simple code:

app.$store.dispatch('simplert/showErrorAlert', {
    alert: app.$refs.simplert,
    title: app.$trans('simplert_error_title'),
    message: response.body,
});

But I want to have that code inside a function easy to call from my components. How should I put it? Inside my vue instance (but not recommended from guide) or inside a plugin (mixin or method?)


Solution

  • I think that I found the right method to manage this scenario. I removed the store module's "simplert" and I copied its functionalities inside a mixin. So I created inside mixin's folder a simplert.js file, where I put all my logic to manage simplert alerts. Then in my components I imported the mixin when I need it. In this way I semplified the manage of simplert and I use it only in the components where need it