I have an action within vuex that I would like to auto dispatch within vuex itself rather than a component.
I have created a notification bar that changes through different notifications which is on multiple pages. Rather than the notifications start from the beginning when I switch page I have created a store to set which notification to show.
I would like to dispatch the rotate function in the vuex store from within vuex rather than from within a component
Please note: I'm using Nuxt
VUEX State: store/notifications.js
export const state = () => ({
section: 0,
notifications: [
'notification 1',
'notification 2',
'notification 3'
]
})
export const mutations = {
INC_SECTION(state) {
state.section ++
},
RESET_SECTION(state) {
state.section = 0
}
}
export const actions = {
rotate({commit, dispatch, state}) {
setTimeout(() => {
let total = state.notifications.length -1
if (state.section === total) {
commit('RESET_SECTION')
}
else {
commit('INC_SECTION')
}
dispatch('rotate')
}, 3500)
}
}
export default {
state,
mutations,
actions
}
VUE JS Component:
<template>
<section class="notifications">
<template v-for="(notification, i) in notifications" >
<p v-if="$store.state.notifications.section === i" :key="i">{{notification}}</p>
</template>
</section>
</template>
<script>
export default {
data() {
return { notifications: [] }
},
computed: {
setData() {
this.notifications = this.$store.state.notifications.notifications
}
},
created() {
this.setData
}
}
</script>
You can call another Vuex action by passing the name of that action as a string as the first argument of dispatch : const store = new Vuex. Store({ actions: { walk(context) { context. dispatch("goForward"); }, goForward(context) { // }, }, });
An action in Vuex is where you perform interaction with APIs and commit mutations. Such interactions are inherently asynchronous.
In Vuex actions are asynchronous. If an action is complete , there is no way to detect that. You can return a Promise to let the calling function know that the action is complete. In the below example myAction returns a Promise.
Actions are similar to mutations, the differences being that: Instead of mutating the state, actions commit mutations. Actions can contain arbitrary asynchronous operations.
There are a lot of much cleaner ways you can do this.
First of all if you are using Nuxt, then, IMO you should be using its awesome feature of middlewares for dispatching actions (your use case of not keeping it, on the component level).
Secondly, Vuex provides us mapGetters
functionality which makes the state properties available in the components while keeping them reactive, at the same time, too.
So, you can go with the following:
Vuex Store:
export const state = () => ({
section: 0,
notifications: ["notification 1", "notification 2", "notification 3"]
});
export const mutations = {
INC_SECTION(state) {
state.section++;
},
RESET_SECTION(state) {
state.section = 0;
}
};
export const actions = {
rotate({ commit, dispatch, state }) {
setTimeout(() => {
let total = state.notifications.length - 1;
if (state.section === total) {
commit("RESET_SECTION");
} else {
commit("INC_SECTION");
}
dispatch("rotate");
}, 3500);
}
};
export const getters = {
notifications(state) {
return state.notifications;
},
section(state) {
return state.section;
}
};
export default {
state,
mutations,
actions,
getters
};
Vue Component:
<template>
<section class="notifications">
<template v-for="(notification, i) in notifications">
<p v-if="section === i" :key="i">{{ notification }}</p>
</template>
</section>
</template>
<script>
import { mapGetters } from "vuex";
export default {
data() {
return {};
},
computed: {
...mapGetters(["notifications", "section"])
}
};
</script>
Middleware
export default function({ store }) {
store.dispatch("rotate");
}
depending on your use case, you can keep this middleware global (attached to routes), or attached to a specific layout.
here is a working sandbox example. hope this will help you out.
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