Vuex+ is an opinionated library that makes Vuex module instances possible.
<counterGroup></counterGroup>
<counterGroup></counterGroup>
<counterGroup instance="foo"></counterGroup>
Enhancements:
- Dynamic root level module instances that can be shared across components
- Instances get their Vuex path extended with their instance name
foo
with instancebar
, becomesfoo$bar
- Instances get their Vuex path extended with their instance name
- Root level instances can be preserved or cleared when components are destroyed
- Module states are decorated with a
$parent
-state object getter- Yes, still serializable states
- Yes, still injectable states through devtools
- Static submodule instances
Vuex+
map.getters and map.actions expand module paths to full paths when component nesting order is same as vuex module nesting order- Automatic Vuex HMR (needs naming conventions)
- Modules are automatically get
name
andnamespaced
parameters set - Works side by side with normal vuex modules. By following the file naming convention they also get full automatic HMR handling.
These enhancements from v1 are deprecated, but still working for now:
- (Generated API with magic strings in all vuex modules for getters/actions/mutations)
- (Generated global API with magic strings for global getters/actions/mutations)
Check out the extensive tutorial bundled with the example: https://github.com/presidenten/vuex-plus-demo
- Webpack
- Naming conventions for:
- Vuex module filenames
- Vuex submodule filenames
Used in main.js
:
default
:
import Vue from 'vue';
import Vuex from 'vuex';
import VuexPlus from 'vuex-plus';
Vue.use(Vuex);
Vue.use(VuexPlus.getVuePlugin(Vue)); // Adds global vuex+ mixin to components
const store = new Vuex.Store({
plugins: [VuexPlus.getVuexPlugin(Vuex)], // Patch vuex for $parent & bootstrap HMR
});
new Vue({
el: '#app',
store,
render: h => h(require('./app.vue').default), // Start application
});
If using vue-loader < v13.0.0, skip .default
on the render line.
Used in vuex modules:
-
store
: Method used to wrap Vuex module definitions to make them intoVuex+ modules
import { store } from 'vuex-plus'; export default store({ state, getters, ... });
-
newInstance
: Wrapper to make new submodule instanceimport { store, newInstance } from 'vuex-plus'; import submodule from './a-submodule.js'; const submodule$foo = newInstance(submodule, 'foo'); const submodule$bar = newInstance(submodule, 'bar'); export default store({ modules: { submodule$foo, submodule$bar, }, });
-
root
: Object used for easy access to various application getters/actions.import { root } from 'vuex-plus';
- Use paths with absolute path to reach anywhere in the application.
root.get{ path: 'a/b$foo/someGetter' }; root.dispatch{ path: 'c$foo/d$bar/someAction', data: 42 };
- Use together with
context.state
for easy access in the same instance tree. Two path keywords expands to path within the instance:'$root'
- Expands to root the level root level module with its instance
root.get({ path: '$root/someGetter', state: context.state }); // expands to root.get({ path: 'a/someGetter' });
'$parent'
- Expands to the parent module with all instances needed
root.get({ path: '$parent/someGetter', state: context.state }); // expands to root.get({ path: 'a/b$foo/someGetter' });
Used in components:
-
root
: Same as above, but only absolute paths work -
map
:Vuex+
own version ofmapGetters
/mapActions
with module namespacing handled, when that the component tree and their vuex models are nested in the same way. If vuex modules are nested like soa b$chuu c
The vuex modules mapping them, needs the same order, even if other components can be squeezed in between:
A(a) // Mapping a Foo B(b) // Mapping b Bar Piri C(c) // Mapping c
map.getters()
andmap.actions()
expand vuex paths and adds parent instances<script> import { map } from 'vuex+'; export default { computed: { ...map.getters({ count: 'c/someGetter', // expands to 'a/b$chuu/c/someGetter' }), }, } </script>
- Resolve
vuex+
asvuex-plus
resolve: {
alias: {
'vuex+': 'vuex-plus',
}
},
- Use
vuex+
loader to add names to module stores
module: {
rules: [
{
test: /-(store|substore)\.js$/,
loader: 'vuex-plus/loader',
},
],
},
- Vuex HMR setup:
plugins: [
new (require('webpack/lib/ContextReplacementPlugin'))(
/webpack-context-vuex-hmr$/,
path.resolve(process.cwd(), './src'),
true,
/-store.js|-substore.js$/
)
],
MIT