I'm trying to add new variables, getters and mutations in the 'created' lifecycle hook in one of my Vuejs components. The variables work fine. But with getters/mutations, it seems it's not as easy as adding new functions to the vuex store object. The problem I'm trying to solve is creating "shared" reusable components.
Here's the component:
<template>
<div>
<h2 class="headline">Number of items:</h2>
<v-select
:items="limits"
item-value="value"
item-text="text"
label="Select"
v-model="selected_limit"/>
</div>
</template>
<script>
import {selectLimitComponentVariables} from './index';
import {selectLimitComponentGetters} from './getters';
import {selectLimitComponentMutations} from './mutations';
export default {
created: function () {
// Add the variables
Object.assign(this.$store.state[this.ns], selectLimitComponentVariables(this.var_prefix));
// Add the getters
Object.assign(this.$store.getters, selectLimitComponentGetters(this.ns, this.var_prefix));
// Add the mutations
Object.assign(this.$store._mutations, selectLimitComponentMutations(this.ns, this.var_prefix));
},
name: 'SelectLimitComponent',
props: {
ns: {
type: String,
default: null
},
var_prefix: {
type: String,
default: ''
}
},
computed: {
selected_limit: {
get () {
return this.$store.state[this.ns].selected_limit;
},
set (value) {
this.$store.commit(`${this.ns}/update${this.var_prefix}selected_limit`, value)
}
},
limits: {
get() {
return this.$store.state[this.ns].limits;
}
}
}
}
</script>
And here are the imported functions. selectLimitComponentVariables:
export const selectLimitComponentVariables = function (prefix) {
return {
[`${prefix}selected_limit`]: '100',
[`${prefix}limits`]: [
{'text': '10', 'value': '10'},
{'text': '50', 'value': '50'},
{'text': '100', 'value': '100'},
{'text': '250', 'value': '250'},
{'text': 'No limit', 'value': '-1'}]}
};
selectLimitComponentGetters:
export const selectLimitComponentGetters = function(namespace, prefix){
return {
[`${namespace}/${prefix}selected_limit`]: state => state[`${prefix}selected_limit`]
}
};
selectLimitComponentMutations:
export const selectLimitComponentMutations = function (namespace, prefix){
return {
[`${namespace}/update${prefix}selected_limit`]: (state, newLimit) => state[`${prefix}selected_limit`] = newLimit
}
};
Is there a way to manually add or register new getters/mutations, after the vuex store is created?
It's better to use store.registerModule
feature of vuex to dynamically add new modules to vuex
this.$store.registerModule(`${this.ns}selected_limit`, {
state: selectLimitComponentVariables...,
getters: selectLimitComponentGetters...,
mutations: selectLimitComponentMutations...,
namespaced: true
})
You can check official document in Dynamic Module Registration
section of https://vuex.vuejs.org/en/modules.html
It looks like what you're trying to do is have per-component Vuex state.
If you modify the Vuex schema at random like that, it would make it very difficult to manage the separation of state (you're just monkey-patching the root Vuex state).
Here's another approach. You could create a separate Vuex module and register it dynamically in the beforeCreate
hook of your component.
Vue.use(Vuex);
const HomeModule = {
namespaced: true,
state() {
return {
count: 0,
};
},
mutations: {
increment(state) {
state.count++;
},
},
};
const ns = 'home';
Vue.component('home', {
template: '<div><button @click="increment">+</button> {{ count }}</div>',
beforeCreate() {
if (!this.$store.state[ns]) {
this.$store.registerModule(ns, HomeModule);
}
},
computed: Vuex.mapState(ns, ['count']),
methods: Vuex.mapMutations(ns, ['increment']),
});
new Vue({
el: '#app',
store: new Vuex.Store(), // Empty root store
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.1.3/vuex.js"></script>
<div id="app">
<home></home>
</div>
ns
global variable here, but you could obtain it from a prop like in your example.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With