Once a Vuex module grow is recommended to divide it into several files composing the different sections, but then it gets interesting to reuse code. For example, there could be several modules dealing with DATA in an exact same way, but not using all the features: one requires selecting data, another requires specific API actions, etc.
A way to solve this is to divide the module into even smaller reusable parts, Data, DataSelection, DataApi, etc. and combine as required when building the module:
import data from './common/data'
import selection from './common/data-selection'
export default {
state: () => ({
...data.state,
...selection.state
}),
getters: {
...data.getters,
...selection.getters
},
mutations: {
...data.mutations,
...selection.mutations
}
}
You may suggest setting those mixins as independent modules, but that is not convenient because modules force the state into objects (state.selection.selection vs state.selection) and adds extra layer of complications when trying to access the state from other mixin.
Instead of the above, a mixin would allow doing:
import data from './common/data'
import selection from './common/data-selection'
export default {
mixins: [data, selection]
}
If this idea doesn't align up with the core base, it would be nice to at least expose some way to allow adding this functionality through a plugin.
Well, at my work we needed something similar so we ended up coding a PoC which are using Object composition to create a final module Object.
Let's explain a bit: we want to compose a Note module and a Draft module. The purpose is to combine two behaviors to get a
This allows us to code one of the modules without taking care of other presence. Only the final module, which will wrap the old one, have to compose the state functions and the rest of the module Object is merged basically. You can check out that in src/store/draft.js but it looks like this:
export default function(store) {
return {
...store,
state() {
const init = store.state();
return {
// Warning, because we do only a spread, the clone is only one level deep.
...init,
__saved: { ...init }
}
},
...
We also tried to use a dynamic module to encapsulate every single data with its own single module (just a tryout, we don't know if it's good from performance PoV) so you might not be interested in that.
Here is the link.
Thanks for sharing @sotaan
has this been merged ? it still sound useful...
It's just a proposal @y-nk, but knowing that Vue is discouraging mixins in favor of the Composition API I assume Vuex will follow the same path, and we could consider this proposal deprecated.
I can confirm.
I was working with @sotaan when we came up with this idea.
We clearly wanted to recreate a composition API on top of the modules.
I followed the idea through, and there are too much limitation for it to be really useful, unfortunately.
I hope Vuex will adopt a compositional API as well instead of the current module API.
I agree, we should think something other than mirin approach. While mixin could be useful to JS users, it would be really tough to type mixin as well.
We're currently investigating how we could align next Vuex with including composition API.
Most helpful comment
Well, at my work we needed something similar so we ended up coding a PoC which are using Object composition to create a final module Object.
Let's explain a bit: we want to compose a Note module and a Draft module. The purpose is to combine two behaviors to get a
This allows us to code one of the modules without taking care of other presence. Only the final module, which will wrap the old one, have to compose the state functions and the rest of the module Object is merged basically. You can check out that in
src/store/draft.jsbut it looks like this:We also tried to use a dynamic module to encapsulate every single data with its own single module (just a tryout, we don't know if it's good from performance PoV) so you might not be interested in that.
Here is the link.