Skip to content

Interact with modules more like components, perhaps even models? #359

Closed
@Sarke

Description

@Sarke

First off, congrats on 2.0!

I like how you can now include getters and actions in the modules, that's a good improvements. However, I think it still could be better. I know Vuex tries to keep the objects simple to work with the mutation tracking and such, but I am used to working with object models and they just make so much sense to me.

Compare how a Vue Component can have a computed value and a real data value. If there is a computed getter then it will be used, if not the data value will be used. I feel something similar would make sense for Vuex modules.

So, imagine we could do something like this?

let user = this.$store.model.user

user.id
// equal to this.$store.state.user.id

user.isAdmin
// equal to this.$store.getters.user_isAdmin

user.login(credentials)
// equal to this.$store.dispatch('user_login', credentials)

user.name = newName
// equal to this.$store.commit('USER_SET_NAME', newName)

The last one, the setter that does a commit, I feel would have the most opposition to implementation, as it hides the whole mutation flow a bit and is the more vague of the four. However, I think these would make a big usability improvement for the Vuex store interactions, and it would be something people would be free to use (or not to use) as it doesn't change how anything else works.

The content of the user.js module would be something like this:

const state = {
    id: 0,
    admin: false,
}

const mutations = {
    [USER_SET_NAME](state, newName) {
        state.name = newName
    },
}

const getters = {
    isAdmin() {
        return state.admin
    },
}

const actions = {
    login({ commit }, credentials) {
        // ... logic
    },
}

export default {
    state,
    mutations,
    getters,
    actions,
    prefix: true, // prefixes actions and getters with 'user_'
    activateModels: true, // makes the store.models available
}

The first option prefix is a way of namespacing the store.getters and store.actions without having to keep repeating that in the module. I am not a fan of how modules all share the same getters and actions names and can overwrite each other, since I (obviously) feel they should be compartmentalized like the components (and models).

The second option 'activateModels' might be a good idea if there are any negative issues with loading the modules into a store.models interface.

Perhaps both options should be global and not per-module options...

I'm very happy with what Vue and Vuex is, and I am looking forward to your thoughts and discussing the suggestion.

EDIT: I'm not sure how this would work with collections of models. Perhaps specifying the id in a third option (defaulting to id) would allow for loading a model from a collection, e.g this.$store.model.user[1] or this.$store.loadModel('user', 1)?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions