Closed piknik closed 8 years ago
I actively avoid classes in all Vue APIs, but the alternative object syntax looks interesting.
In fact, you can do something like this right now:
// in a module, cart.js
// the module passed to store constructors, same as before
export default {
state: { ... }
mutations: { ... }
}
// extra named export as a Vue component mixin
export const mixin = {
getters: { ... },
actions: { ... }
}
In component:
import { mixin as vuexCartMixin } from 'src/vuex/modules/cart'
export default {
mixins: [vuexCartMixin]
}
One drawback I see with this is that it is no longer explicit in the component itself what properties and actions are exposed as a result of using Vuex. You'd have to checkout the module code to see what getters/actions are available. But it could indeed be much less verbose.
I understand the issue with classes.
Your use of mixins are interesting, something more like what can be implemented, though I don't believe it would work as it is; how does the store and state variables get put into the parameters of the action and getter functions? EDIT: Also, the getters and actions don't have some reference to the store/state internally, which would make parameters unneccesary, and a nice to have.
In my experience, I really wished there was a way to differentiate between different sets of getters by their module name, like cart.allItems
and bag.allItems
, instead I have to do allCartItems
and allBagItems
. Not that it's wrong, but I can analyze which module the getter comes from quicker. At the same time, it reduces polluting the component with potentially a lot of references to getters and actions.
@piknik that's a good point - I think allowing component vuex
option to take in modules is probably a good idea, but I would avoid using string ids:
import cart from 'src/vuex/modules/cart'
export default {
vuex: {
modules: {
cart
}
}
}
When you import actions/getters via a module, they get auto-nested under the name of that module, so you get this.cart.doStuff()
.
@yyx990803 so in that case, what structure should the cart have in order to do this.cart.getItems()
?
I'm struggling to organize my medium-large sized app, I need to call something like this.products.getAll()
, this.cart.getAllProducts()
(or this.products.all
), that separation by modules in the calling component seems ver good though.
Also, keep in mind that actions should not be per store because an action can call shared mutations. I would say that actions should be per "service" or something like that.
This may not be completely on topic - but I see the benefit of being able to import at least getters via the module interface. If you have the mutations and the state namespaced via the module object, then it makes sense to have getters that are similarly namespaced, so that you do not have to redundantly specify the namespace within those getters (and in fact, you can reusably import those getters into different modules when you have common getter behaviour across different modules).
Please see #236
I have this idea from #148 that I think would make programming large projects a ton easier, and maybe others would find it very useful. However, I'm not sure if it breaks the redux pattern itself and thus the point of Vuex, though it seems to fit in quite well. See how this could be used with some pseudocode below.
Introduction
Taken from #148, with proper modifications:
Then in a Vue component, the module and its getters and actions can be referenced. Notice how the case of the class changes to camelCase:
Global
Also, if you need some actions and getters that aren't relative to the module(s) you're targetting, simply do as you were with global getters and actions:
actions.js
Would be nice to have those automatic getters and setters, for these ones...
Bonus Outcomes
Some other uses I could think of, since we have a constructor for the modules we could do things like this in the future:
This way Vuex handles loading and storing state automatically and theres not so much of this everywhere:
A different way
And if classes aren't anyone's thing, it could be done using object syntax:
Conclusion
Of course, all of this class stuff can be made optional, and the original redux-like syntax can be used alongside it.
If this is a good idea, I'd gladly implement this into Vuex myself after I finish my current project, which is within the week.