【问题标题】:Is there a created() for vuex actions to auto dispatch是否有用于自动调度 vuex 操作的 created()
【发布时间】:2019-06-16 11:26:07
【问题描述】:

我在 vuex 中有一个动作,我想在 vuex 本身而不是组件中自动调度。

我创建了一个通知栏,可以通过多个页面上的不同通知进行更改。我创建了一个商店来设置要显示的通知,而不是在我切换页面时从头开始通知。

我想从 vuex 内部而不是从组件内部调度 vuex 存储中的旋转函数

请注意:我使用的是 Nuxt

VUEX 状态: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 组件:

<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>

【问题讨论】:

    标签: javascript vue.js vuex nuxt.js


    【解决方案1】:

    有很多更简洁的方法可以做到这一点。

    首先,如果您使用 Nuxt,那么,IMO 您应该使用其出色的 middlewares 功能来调度操作(您的用例是在组件级别不保留它)。

    其次,Vuex 为我们提供了mapGetters 功能,它使组件中的状态属性可用,同时保持它们的反应性。

    因此,您可以使用以下方法:

    Vuex 商店:

    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 组件:

    <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>
    
    

    中间件

    export default function({ store }) {
      store.dispatch("rotate");
    }
    
    

    根据您的用例,您可以将此中间件保持为全局(附加到路由)或附加到特定布局。

    这是一个有效的sandbox 示例。希望对您有所帮助。

    【讨论】:

    • 感谢您抽出宝贵时间提供帮助。这仅在我更改路线时有效,并且每次更改路线时都会触发它,因此我遇到与以前相同的问题。有没有办法只在初始站点加载时触发中间件?
    • 为了解决这个问题,我创建了一个插件而不是名为 onload.js 的中间件:export default function ({ app, store }) { app.router.onReady(() =&gt; store.dispatch("rotate")) } 并更新了 nuxt.config.js plugins: [ {src: '~/plugins/onLoad.js', ssr: false} ]
    猜你喜欢
    • 2021-05-04
    • 2021-11-28
    • 2022-01-23
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    • 2018-12-27
    • 2020-02-24
    • 2018-05-31
    相关资源
    最近更新 更多