是否有一个 create() 用于 vuex 操作自动调度

Nat*_*ate 5 javascript vue.js vuex nuxt.js

我在 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
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

wal*_*ali 4

有很多更干净的方法可以做到这一点。

首先,如果您使用 Nuxt,那么,在我看来,您应该使用其出色的中间件功能来分派操作(您的用例是在组件级别不保留它)。

其次,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
};

Run Code Online (Sandbox Code Playgroud)

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>

Run Code Online (Sandbox Code Playgroud)

中间件

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

Run Code Online (Sandbox Code Playgroud)

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

这是一个工作沙箱示例。希望这能帮助你。

  • 感谢您抽出时间来提供帮助。这仅在我更改路线时有效,并且每次更改路线时都会触发它,所以我遇到了与以前相同的问题。有没有办法仅在初始站点加载时触发中间件? (2认同)
  • 为了解决这个问题,我创建了一个插件,而不是名为 onload.js 的中间件: `export default function ({ app, store }) { app.router.onReady(() =&gt; store.dispatch("rotate")) }`并更新了 nuxt.config.js `plugins: [ {src: '~/plugins/onLoad.js', ssr: false} ]` (2认同)