javascript - 是否有一个 created() 用于自动调度 vuex Action

标签 javascript vue.js vuex nuxt.js

我在 vuex 中有一个 Action ,我想在 vuex 本身而不是组件中自动分派(dispatch)。

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

我想从 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>

最佳答案

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

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

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

因此,您可以执行以下操作:

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例子。希望这对您有所帮助。

关于javascript - 是否有一个 created() 用于自动调度 vuex Action ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54317639/

相关文章:

vue.js - 使用新版本自动更新 Vue 站点/PWA

html - 带有 svg 的对象标签填充了整个网页

vue.js - 如何在 Vue.js 应用程序中使用本地版本的数据对象?

vue.js - vuex 完成后加载时设置 false

javascript - Vuex Store Module 访问状态

javascript - 对象作为 React 子对象无效 - 文本输入

javascript - 为什么单独定义 JS 原型(prototype)函数比在字典中更快?

JavaScript 删除 tld 后面和空格之前的所有内容

javascript - 文件选择器 : How to pick an audio file based on users choice and play using a button

javascript - 将数据(文本)复制到 Vue 中的剪贴板(Nuxt js)