Is there a created() for vuex actions to auto dispatch

不羁岁月 提交于 2019-12-11 07:57:34

问题


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>

回答1:


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.



来源:https://stackoverflow.com/questions/54317639/is-there-a-created-for-vuex-actions-to-auto-dispatch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!