Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

declare mapState and mapMutations globally in SPA VueJS

I am creating a basic SPA, but it happens that the states I manage with Vuex and the mutations up there all right, but in each component that I want to use mapState and mapMutations I have to import them locally.

<script>
    import {mapState,mapMutations  } from 'vuex';
    export default{
        computed : mapState(['isLoggedIn']),
        methods: {
            ...mapMutations(['logout'])
        }
    }
</script>

This is the correct way to do it? Or how can I declare them globally and avoid importing in each component so that it is as follows?

<script>   

    export default{
        computed : mapState(['isLoggedIn']),
        methods: {
            ...mapMutations(['logout'])
        }
    }
</script>
like image 851
DarkFenix Avatar asked Apr 09 '18 20:04

DarkFenix


1 Answers

Quick solutions

The Vuex helpers like mapMutations etc. returns an object populated with functions which assumes that this.$store is a Vuex store.

Store service

If you need to use the store in vanilla JS and you don't want to expose the store module everywhere, you could define a service module.

import { mapActions } from 'vuex';
import $store from '@/store';

/**
 * Simple mapping of the Vuex store UI module.
 * @module services/ui
 * @property {Function} pushMessage
 */
export default Object.assign({
    $store,
}, mapActions('ui', ['pushMessage']));

Now, using it is as simple as importing the service module.

import ui from './services/ui';

// triggers the `pushAction` on the ui namespaced store module
ui.pushMessage({ content: 'whatever' });

Vue mixin

To have default computed and methods on a Vue component, you can create a simple mixin to import in specific components.

import { mapState, mapMutations } from 'vuex';

export default {
    computed : mapState(['isLoggedIn']),
    methods: mapMutations(['logout'])
}

Then, use the mixin in a component.

<script>
import mixin from './mixin';

export default {
  mixins: [mixin],
  data() {/* ... */},
  // etc.
}
</script>

Global mixin

If you really want each component to have this default mixin without having to explicitly define it, use a global mixin.

import Vue from 'vue';
import { mapState, mapMutations } from 'vuex';

export const mixin = {
    computed : mapState(['isLoggedIn']),
    methods: mapMutations(['logout'])
};

Vue.mixin(mixin);

Personally, as a standard, I never map the state or mutations.

I only map getters and actions so my components don't need to know the state structure and that an action is async or not. I see getters and actions as the public API of a Vuex store (or any similar store, like Redux).

I also only map the relevant data. Components responsibility is to interact with the user of the app, displaying and handling events and nothing more. If all your components need the user object, maybe they're doing too much and that logic should probably be moved elsewhere, like in an action.

See more on Vue communication

like image 78
Emile Bergeron Avatar answered Oct 30 '22 06:10

Emile Bergeron