Hello wonderful programmers, I'm trying to stop doing something like this in my vues:
import {getAvailableShapes, getAllMatWidths, getAllMatWidthPairs, getAvailableMatLengths, getCompositionWidth, getAvailableTopColors, getAvailableBottomColors} from 'store/getters'
import {changeWidth, changeLength, selectTopColor, selectBottomColor, selectShape} from 'store/actions'
//... etc
export default {
//...etc
vuex: {
getters: {getAvailableShapes, getAllMatWidths, getAllMatWidthPairs, getAvailableMatLengths, getCompositionWidth, getAvailableTopColors, getAvailableBottomColors},
actions: {changeWidth, changeLength, selectTopColor, selectBottomColor, selectShape}
}
//...etc
}
Obviously the above gets very verbose, this is one of my smaller vues, you can only imagine larger ones I have, how that would look.
I was thinking of just importing all the getters and actions in each of my components, like so:
import * as getters from 'store/getters'
import * as actions from 'store/actions'
//...etc
export default {
//...etc
vuex: { getters, actions }
}
However, I am not sure of how performant this would be since there are lots of getters and actions. Are they cached? References? I wasn't sure, so I thought to do this a different way:
import {makeGetters, makeActions} from 'store'
//...etc
export default {
//...etc
vuex: {
getters: makeGetters('getAvailableShapes', 'getAllMatWidths', 'getAllMatWidthPairs', 'getAvailableMatLength', 'getCompositionWidth', 'getAvailableTopColors', 'getAvailableBottomColors'),
actions: makeActions(/* as above */)
}
}
//store/index.js
export function makeGetters(...requestedGetters) {
let result = {}
for (let request of requestedGetters) {
result[request] = getters[request]
}
return result
}
export function makeActions(...requestedActions) {
let result = {}
for (let request of requestedActions) {
result[request] = actions[request]
}
return result
}
I'd love to get rid of the verbosity as much as possible. Could I get some info on whether the second way is good enough, or should I stick with my custom way? I'd love to see something like how I defined required getters and actions if that's the case, would make for an excellent version 1.
On another note, notice how I prefixed my getters with _get_. I found myself getting confused over my function names. Is there a good way to somehow namespace them?
Are these getters shared across multiple components? I'd recommend just using inline getters whenever possible and only extract them when they are needed in multiple places.
I have a lot of getters that are shared across components, although I sure could inline some of them it doesn't provide me with a solution. This is a large project and it gets more and more difficult to keep track of inline getters that may potentially be re-used (which I have found out to be so). So I decided to simply keep all the getters together but now face the issue above.
It would be satisfying if I can just import all of the getters without worrying about performance/memory cost...
For another reason to keep getters in one location, if I were to change how the state data is stored, changing the single getter in one location would be easier than changing inline getters in many components.
+1 for automatic getters/actions...getting real tired of importing everything again and again.
// foo-module.js
export const FOO_MODULE = {
state: {
foo: ...,
bar: ...
}
}
/* Getters */
export const foo = state => state.FOO_MODULE.foo // This is annoying too, writing the module name again and again...
export const bar = state => state.FOO_MODULE.bar
.......this goes on and on.....
/* Actions */
export const fetchFoo = () => {...}
export const fetchBar = () => {...}
.......this goes on and on.....
and in every other component that needs these getters/actions
// some component
import {foo, bar, fetchFoo, fetchBar, ......} from '../foo-module';
export default {
vuex: {
getters: {foo, bar, ......}
actions: {fetchFoo, fetchBar, ......}
}
}
Maybe getters/actions can be hooked onto store modules?
and instead of importing all those functions, we simply import that module and call it's methods?
import fooModule from 'foo-module';
export default {
vuex: {
modules: {fooModule}
}
}
@fnlctrl Your last statement gave me a good idea I think... What if we transformed modules into ES6 classes, instead of utilizing 2 objects, state and mutations? Then a "module" would look something like this maybe?
import * as Mutation from './mutations'
export default class Cart {
constructor() { //defining the state
this.all = []
this.status = "good"
this.unaccountedFee = 60
// Global state object inserted by Vuex (this.state?)
}
getAllItemsById() {
return this.all.map(item => item.id)
}
getItemsMappedProducts() {
//Accessing a module elsewhere
return this.all.map(item => this.state.products.all.find(item.productId))
}
postItems(message) {
this.dispatch(Mutation.CART_POST)
//return some ajax promise
}
//mutations: (too bad there aren't such thing as annotations yet!)
[Mutation.ADD_TO_CART] (item) {
this.all.push(item)
}
[Mutation.CART_POST] () {
this.status = 'posting'
}
}
Something like the above is remeniscent of Java persistence models, but at a global scope instead. This makes a lot more sense imo, there is less passing around the store/dispatch/state as a parameter in actions and getters, and it would still be possible to make 'out of module' actions and getters, if necessary. Then, all that would be necessary in vue components would be something like this:
export default {
//...
vuex: {
modules: ['Cart']
},
methods: {
test() {
this.cart.getAllItemsById()
}
}
}
I believe the entire premise of the redux pattern is based on ES5 javascript, not that it's a bad thing, but ES5 doesn't have classes, so 'workarounds' like passing the state in parameters need to be done. Since it's so easy to make classes in es6 now, it seems kind of dated to me.
Let me know what you think @yyx990803
See my comment here - let's continue the discussion over there.
Most helpful comment
@fnlctrl Your last statement gave me a good idea I think... What if we transformed modules into ES6 classes, instead of utilizing 2 objects, state and mutations? Then a "module" would look something like this maybe?
Something like the above is remeniscent of Java persistence models, but at a global scope instead. This makes a lot more sense imo, there is less passing around the store/dispatch/state as a parameter in actions and getters, and it would still be possible to make 'out of module' actions and getters, if necessary. Then, all that would be necessary in vue components would be something like this:
I believe the entire premise of the redux pattern is based on ES5 javascript, not that it's a bad thing, but ES5 doesn't have classes, so 'workarounds' like passing the state in parameters need to be done. Since it's so easy to make classes in es6 now, it seems kind of dated to me.
Let me know what you think @yyx990803