Tips for organizing intricate views with vuex

After using vuex for a few months, I'm starting to question if I am utilizing it correctly.

The main issue I am facing is, How should I organize my states in a modular way?

For example:

I have a view where users can create and edit a resource (post). To create or update a post, I need to make API calls to fetch data such as the list of available categories and tags. Where should I keep this data? Should it be in vuex/modules/post.js? Or in separate modules like vuex/modules/tags.js and vuex/moduels/categories.js?

Currently, I am storing post's tags and categories in vuex/modules/post.js, but what about all the other resources needed to modify a post (like all available tags and categories that can be selected by the user)?

What about the list of posts? Should I store the list in vuex/modules/post or in its own module like vuex/modules/posts-list.js?

Should each view have its own separate 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);
        }
    }
}

Answer №1

When it comes to organizing domain-related data, the choice is yours. Personally, I prefer storing all domain-specific information (like post tags, categories, and posts themselves) in a dedicated module. For instance, if I were working on another domain, such as products, I would create a separate module called products.js that contains its own set of tags, categories, etc.

Thanks to Vuex's namespaced modules, you can easily specify which tags you want to access:

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

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Populating Hidden Form Fields with Dynamic Identifiers

I'm facing an issue with a form where I need to input a value into a hidden field upon clicking a button. Despite using unique IDs for all elements, the data is not being submitted in the POST request. The IDs are unique because there are multiple f ...

Adjusting the XHR 'Referer' header within a Chrome application

Is there a way to adjust the 'Referer' header in my Chrome app? When I try to set it using the following code: xhr.setRequestHeader('Referer', 'http://example.com/'); I receive an error message that says: ajax.js:15 Refused ...

What is the most efficient way to organize an array by date?

Here is the data I have: const data = [{date: "2022-05-10 13:36:00", open: 155.535, low: 155.4, high: 155.67, close: 155.44}, {date: "2022-05-10 13:35:00", open: 155.23, low: 155.2102, high: 155.62, close: 155.53}, {date: "2022-05 ...

Sending data using the AJAX method with integers

Utilizing AJAX to send a high score to a SQLite database's highScores table, the total of the high score must be calculated through a query and then retrieved back from the database. How can I ensure that the score is sent as an integer through AJAX t ...

Disabling Commands using Discord JS Commando in a guild

Curious about something. Will Discord JS Commando disable a command only within a specific server (guild) or globally across all servers? ...

Is there any difference in loading speed when using an async function in the createConnection method of promise-mysql?

Is it more efficient to use asynchronous createConnection or not? Does this impact the loading speed in any way? I am working with express, ReactJS, and promise-mysql. Which approach is preferable? Option 1: async connect () { try{ ...

WebWorker - Error in fetching data from server using Ajax call

I've been experimenting with making AJAX calls to an ajax.htm file using web workers. The goal is to have the data continuously updated at set intervals. Although I'm not seeing any errors and the GET request appears to be successful, the data i ...

Problems encountered when attempting to create a link between two nodes on a force-directed graph using a mouse click

I'm currently working on creating an interactive graph where users can click on two nodes to establish a link between them (which can be removed later). My approach was inspired by Mike Bostock's example at: https://bl.ocks.org/mbostock/1095795 ...

How do I prevent my image slider from scrolling to the top of the page when I click next or prev?

<script> export default { name: "ImageSlider", data() { return { images: [ "https://cdn.pixabay.com/photo/2015/12/12/15/24/amsterdam-1089646_1280.jpg", "https://cdn.pixabay.com/photo/2016/02/17/2 ...

Error Encountered in Selenium WebDriver Javascript: Unable to locate variable: $

My goal was to utilize Selenium Webdriver to click a button on a web page. I was able to successfully achieve this using Chrome Developer Tools, however, I encountered a "can't find variable" error when executing Javascript code: IJavaScriptExecutor ...

A self-destructing javascript/jquery function that removes itself after running

For a very detailed analytics insight, I am sending an ajax request to my controller in order to update the user's interaction (such as which pages they visit or like) and store this information in my MongoDB. All I want is for this script to be dele ...

Updating AngularJS: Removing the hashtag using history.pushState()

Struggling to enhance the aesthetics of the URLs in my AngularJS application, I am facing some challenges. While I can access the "/" route without any issues, the "/about" route seems to be out of reach. Please note that the project is situated at (loc ...

jQuery.ajax Failure Response

When using MVC on the server side and calling a function with jQuery.Ajax that returns JSON, an exception is being thrown. How can I invoke the error handling function of Ajax by sending something back in the return JSON function? MVC Function public Jso ...

Initiating and pausing an Interval using a single button

I'm attempting to create a JavaScript-based chronometer that starts and stops when a single button is clicked. However, I am struggling to figure out how to properly implement the setInterval function to achieve this functionality. Below is my current ...

The sluggish performance of my website is being caused by the livereload process that was inserted into my index.hml file, causing it

Recently, I've noticed that this line of code is being inserted dynamically into my index.html file, either through Grunt tasks or directly from the server in Heroku. <script type="text/javascript">document.write('<script src="' + ...

Seeking a straightforward and powerful list for bugs and features that allows users to easily vote and prioritize

I am searching for a simple Javascript or PHP code that allows users to add items to two separate lists and either vote or rate those items. One list is for suggesting and rating features, while the other list is for identifying and voting on bugs that nee ...

Insert information into the window before it loads

Exploring the process of opening new windows using JavaScript. var myWindow = window.open(); myWindow.document.write('html'); Is it feasible to inject content into the document before the window fully loads? I aim to include a complete HTML str ...

Validate that a string is a correct file name and path in Angular without using regular expressions

Currently, I am using regex to determine if a string is a valid file name and path. However, when the string length becomes longer, it ends up consuming a significant amount of CPU, resulting in browser performance issues. public static readonly INVALID_F ...

After clicking on the checkbox, req.body.task becomes undefined

Whenever I click on the checkbox, the value of req.body.task returns as undefined. <input type="checkbox" name="task" autocomplete="off" checked="" onchange="onToDochange({{id}})"> This function is triggered by a change event on the checkbox and it ...

Getting headers from an HTTP response in VueJS is a common task that many developers encounter

I am utilizing axios to fetch data from the backend. After sending a request, I receive a response; however, I am struggling to read some of my headers. The headers that I need to access are 'content-type', 'content-length', 'x-wp- ...