In Vuex, how do I access the root state from the state definition within a namespaced module? - vuex

I'm using Vuex 3.2.0 with modules.
In one of my modules I need access to the rootState from within the initial state: { ... } definition. How do I do this?
// my-module.js
export default {
namespaced: true,
state: {
// I can't actually use `rootState` here so how do I access it?
foo: rootState.appConfig.bar + 'baz';
},
mutations: { ... },
actions: { ... },
getters: { ... }
}
I don't want to use a getter without any actual state value because I need to be able to mutate this value.

Related

Dynamic store value in Vuex

I have a simple store, and I want to have a store value that sums up all the values in an array automatically, but I am unsure what is the best approach with mutations, methods or computed values.
export default {
namespaced: true,
state: {
my_list_values: [10,9,10],
list_sum: 29
}
}
I would like for the list_sum value to function that sums up my_list_values.
You can make use of getter which holds your logic for listSum and can be used in components
export default {
namespaced: true,
state: {
my_list_values: [10,9,10],
}
getters: {
listSum (state) {
//logic to sum values
}
}
}
You can use this getter anywhere in your components as below
import { mapGetters } from 'vuex'
computed: {
...mapGetters([
'listSum',
// ...
])
}
OR
this.$store.getters.listSum
For Ref : Getters

How pass state vuex on created()

I have been using vuex for a project for a few days now. Now I need to pass the value of a state to the created method.
Below I show the code used.
Store file
state: {
friendstatus: null
},
mutations: {
SET_FRIEND_STATUS: (state,friend) => {
state.friendstatus = data;
},
actions: {
getFriendStatus: ({commit},data) => {
//axios request returns friendstatus
commit('STATE_FRIEND_STATUS',response.data.status)
}
Vue component
computed: {
...mapstate('friend',['friendstatus'])
},
created() {
//Here I need to pass friendstatus. Obviously if I call this.friendstatus it does not work.
this.$store.dispatch('friend/getFriendStatus);// I would like to call the state and not the action
}

How do correctly add a getter to a Vuex Module?

I'm trying to create a Vuex module whenever I register the module, I get a state is undefined, even though there is nothing calling the getter I had just made. I'm able to call actions correctly with no errors.
This is my module. customer.js
export default {
namespaced: true,
state: {
login: false,
},
getters: {
isLoggedIn: (state) => {
console.log(state);
state.login;
}
},
mutations: {
set_login: (state, login) => {
state.login = login;
},
set_orders: (state, orders) => {
state.orders = orders;
},
},
actions: {
newsletter_subscribe: (context, email) => {
//- TODO
},
}
}
I have register via the registerModule function.
import Customer from './customer';
store.registerModule('customer', Customer, {
preserveState: true
});
Whenever I have developer tools open it just alerts me that.
Uncaught ReferenceError: state is not defined
at isLoggedIn (customer.js:11)
at wrappedGetter (vuex.esm.js:734)
Am I doing anything wrong with my getter?
I've only noticed the getter being called with Vue Dev tools open as I tried putting an alert in the getter to see what else could be triggering without the state being passed in.
I managed to solve it by giving my store a blank state!
const store = new Vuex.Store({
state: {}
});
And registering modules as normal.

Vuex rootActions with several modules

I have a vuejs on client side, where I use vuex for state management. I have several modules (in separate files) but some of the modules, has very similar actions, that's why I want to create dry code.
My goal: Creating a root action, what can be called by every modules.
My main vuex looks like this:
export default new Vuex.Store({
actions: {
rootactions,
},
modules: {
users,
classes,
studentgroups,
// ... other stuff
}
})
How should I refer the rootactions methods?
Thanks for the responses in advance!
"To dispatch actions or commit mutations in the global namespace, pass { root: true } as the 3rd argument to dispatch and commit."
{
root: true
}
https://vuex.vuejs.org/guide/modules.html
How about to create a separate file RootActions.js with the common actions
export default {
action1: () => {
//
},
action2: () => {
//
},
}
And then import it in your module file e.g. User.js
import RootActions from './RootActions'
const state = {
// state object
}
const mutations = {
// mutations object
}
const actions = {
// actions object
}
export default {
namespaced: true,
state,
mutations,
actions: Object.assign(RootActions, actions)
}

How to create getters and setters for vuex namespaced module state

If I have a Vuex module which is namespaced, how to create the getters and setters for the states in that module when using these state in Vue components?
// My component
new Vue({
computed: {
// How do I add setters also below????
...mapState('nameSpacedModA', {
a : state => state.a,
// ...
},
// Following will only add getters..
// How to add setter ???
...mapGetters('nameSpacedModA', {
a: 'a',
b: 'b' //, ...
}
}
I am binding 'a' to a text input on a form using v-model and then when I edit the control value, Vue is giving error:
[Vue warn]: Computed property "a" was assigned to but it has no
setter.
How to solve this?
If you want do do 2 ways binding, you need to defined both getter and setter in computed properties. (Don't forget to define mutation updateA)
<input v-model="a">
// ...
computed: {
a: {
get () {
return this.$store.state.a
},
set (value) {
this.$store.commit('updateA', value)
}
}
}
Another option is using mapFields
I found another way using Vuex mapStates and mapActions helpers.
This is slightly more verbose. So using the v-model binding approach is more better.
// BTW: If you use the approach as suggested by ittus then you will use the v-model binding like below:
<input v-model="a" />
// Using the other approach that I used you will have to do two-way binding as below:
<input :value="a" #input="updateA" />
If you want to use the v-model binding then the code will be something like below:
// Vuex store
....
modules: {ModuleA, ...}
// ModuleA of store
export default {
namespaced: true,
states: {
a: '',
},
mutations: {
updateA: (state, value) => state.a = value
},
actions: {
updateA(context, value) { context.commit('updateA', value) }
}
}
// Then in your Component you will bind this Vuex module state as below
new Vue({
store,
computed: {
a: {
get() { this.$store.state.ModuleA.a; }
set(value) {this.updateA(value);}
},
},
methods: {
...mapActions('MyModule', [ updateA ]),
}
})