Mohammad Mirzaee
Mohammad Mirzaee

Reputation: 111

How to modularize complex view using vuex

After couple of month using vuex, I'm not sure that I'm using this in the right way.

My main question is, How should I modularize states?

For example :

I have a view to create and edit a resource (post). To create or update a post I need some API calls to fetch some data (like list of all available categories and tags). where should I store them? in vuex/modules/post.js? Or in a dedicated module like vuex/modules/tags.js and vuex/moduels/categories.js?

I'm storing post's tags and categories in vuex/modules/post.js but how about all of other resources that are needed in order to modify a resource (Like all of available tags and categories to be selected by the user )?

How about list of posts? Should I store list of posts in vuex/modules/post or in a dedicated vuex/modules/posts-list.js?

Should every view have it's own module?

// vuex/modules/post.js

import Vue from 'vue';
import Axios from 'axios'

export default {
    namespaced: true,
    state: {
        title: null,
        slug: null,
        tags: [],
        categories: [],
        meta: {},
        excerpt: null,
        content: null,
        comments: []
    },
    mutations: {
        SET_TITLE(state, title) {
            state.title = title;
        },
        SET_SLUG(state, slug) {
            state.slug = slug;
        },
        SET_EXCERPT(state, excerpt) {
            state.excerpt = excerpt;
        },
        SET_CONTENT(state, content) {
            state.excerpt = content;
        },


        ADD_TAG(state, tag) {
            state.tags.unshift(tag)
        },
        REMOVE_TAG(state, index) {
            Vue.delete(state.tags, index);
        },
        SET_TAGS(state, tags) {
            state.tags = tags;
        },


        ADD_CATEGORY(state, category) {
            state.categories.unshift(category)
        },
        REMOVE_CATEGORY(state, index) {
            Vue.delete(state.categories, index);
        },
        SET_CATEGORIES(state, categories) {
            state.categories = categories;
        },


        ADD_META(state, {key, value}) {
            Vue.set(state.meta, key, value)
        },
        REMOVE_META(state, key) {
            Vue.delete(state.meta, key);
        },
        UPDATE_META(state, {key, value}) {
            state.meta[key] = value;
        },
        SET_META(state, meta) {
            state.meta = meta;
        }
    },
    actions: {
        save({state}) {
            Axios.post('http://myapi.com/posts', state);
        },
        async load({commit}, id) {
            const {data} = await Axios.get(`http://myapi.com/posts/${id}`);
            commit('SET_TITLE', data.title);
            commit('SET_SLUG', data.slug);
            commit('SET_EXCERPT', data.excerpt);
            commit('SET_CONTENT', data.content);
            commit('SET_TAGS', data.tags);
            commit('SET_CATEGORIES', data.categories);
            commit('SET_META', data.meta);
        }
    }
}

Upvotes: 0

Views: 163

Answers (1)

Andrew Vasylchuk
Andrew Vasylchuk

Reputation: 4779

It's completely up to you. I would store all domain related data (such as post tags, categories, posts itself) in dedicated module. But if i had another domain (for example products) i woluld create another module (products.js) that would have own tags, categories etc.

Thanks to Vuex namespaced modules it would be clear which tags do you want to access:

// get post tags
this.$store.getters["post/tags"];
{ ...mapGetters("post", ["tags"]) }

// get products tags
this.$store.getter["products/tags"];
{ ...mapGetters("products", ["tags"]) }

Upvotes: 3

Related Questions