NuxtServerInit在Vuex模块模式下不起作用-Nuxt.js

时间:2019-02-28 12:26:35

标签: vue.js vuex nuxt.js vuex-modules

NuxtServerInit在nuxt js vuex模块模式下的初始页面渲染上不起作用。但它适用于经典模式。以下代码是我使用的流程。

我的api调用

api / CategoryApi.js

import axios from 'axios';

const HEADERS = {
    Accept: 'application/json'
};

export default {
    getCategory(payload) {
        return axios.get(`${process.env.apiUrl}/category`, {
            payload,
            headers: HEADERS
        });
    }
}

store / modules / CategoryStore.js

import api from '~/api/CategoryApi'

const state = () => ({
    categories: []
});

const getters = {
    allCategories: state => state.categories
};

const actions = {
    async nuxtServerInit({commit}) {
        const payload = {
            per_page: 6,
            page: 1
        };
        const response = await api.getCategory(payload);
        commit('setCategories', response.data.data);
    },
};

const mutations = {
    setCategories: (state, data) => {
        state.categories = data;
    }
};

export default {
    state,
    getters,
    actions,
    mutations
}

pages / index.vue

<template>
    <div>
        <v-flex xs6 sm4 md2 class="text-xs-center my-2 pa-2" v-for="category in allCategories" :key="category.id">
            {{ category.name }}
        </v-flex>
    </div>
</template>

<script>
    import { mapGetters } from 'vuex';

    export default {
        layout: 'default',
        computed: {
            ...mapGetters({
                allCategories: 'modules/CategoryStore/allCategories',
            })
        },
    }
</script>

我做错了吗? :/我想知道实现此目标的正确方法。

编辑:我对Aldarund的回答(这可能会对某人有所帮助)

编辑后的store / modules / CategoryStore.js

const actions = {
    async fetchCategories({commit}) {
        const payload = {
            per_page: 6,
            page: 1
        };
        const response = await api.getCategory(payload);
        commit('setCategories', response.data.data);
    },
};

添加了store / index.js

const actions = {
    async nuxtServerInit({dispatch}) {
        await dispatch('modules/CategoryStore/fetchCategories');
    },
};

export default {
    actions
}

5 个答案:

答案 0 :(得分:1)

docs

中所述
  

如果您正在使用Vuex商店的模块模式,则仅主   (在store / index.js中)模块将收到此操作。你需要   从那里链接您的模块动作。

因此您需要将nuxtServerInit放入store / index.js

答案 1 :(得分:1)

仅在store / index.js中调用nuxtServerInit是不正确的

我认为最让我困惑的是模块化方法与仅拥有一个存储文件之间的区别。在后一种方法中,我将执行以下操作:

nuxtServerInit(vuexContext, {req, redirect, params})
    {
      vuexContext.dispatch('someAction',someArguments)
    }

在调用模块(例如store / modules / auth.js)时,您不能使用vuexContext,而是直接使用dispatch:

nuxtServerInit({dispatch})
        {
          dispatch('someAction',someArguments)
        }

这对我有用,希望对您有帮助

答案 2 :(得分:0)

尝试使用该代码,清除文件index.js,然后在服务器控制台上运行您看到的消息。

     export const actions = {

  nuxtServerInit ({ dispatch }) {
    console.log("troololollo")
  }
}

也许也可以尝试nuxt.config.js

module.exports = {
  //mode: 'spa',
  mode: 'universal',

答案 3 :(得分:0)

这些问题的许多答案都引用了文档,但没有提到如何真正“从 [index.js] 链接你的模块操作。”

posts.js

export const actions = {
  // This isn't called unless it is "chained"
  nuxtServerInit(vuexContext, context) {
    return new Promise((resolve, reject) => {
      // do a thing
      resolve()
    })
  },
}

index.js

import { actions as postActions } from './posts' ;

export const actions = {
  nuxtServerInit(vuexContext, context) {
    return new Promise(async (resolve, reject) => {
      // "chain" the desired method
      await postActions.nuxtServerInit(vuexContext, context)
      resolve();
    })
  }
}

答案 4 :(得分:0)

我在这个问题上花了很多时间。我将尝试在此处用示例代码总结我的发现,以一劳永逸地解决此问题。

是的,NuxtJS 的文档确实说过,一旦您将 Vuex 构建为模块。然后,您的模块的 nuxtServerInit 将不会被调用。

除非您在 store/index.js 上触发它。

https://nuxtjs.org/docs/2.x/directory-structure/store#the-nuxtserverinit-action

之前我们的Vuex结构是这样的。

store/modules/user.js
store/modules/todo.js
store/index.js

因此,您将初始化 index.js 中的模块,并将新模块方式推进到 Vue 3。您仍然需要 index.js 来触发您的 nuxtServerInit

模块方法的新 Vuex 结构是这样的。

store/user.js
store/todo.js
store/index.js

是的,您只需将其从您的模块包中取出并移至您的商店包中即可。

现在,让我们从 todos.nuxtServerInit 触发 store/index.js

'/store/index.js'
import todos from './todos'

const state = () => ({})
const getters = {}
const mutations = {}

const actions = {
  nuxtServerInit(vuexContext, context) {
    return Promise.resolve(
      new Promise((resolve, reject) => {
        todos.actions.nuxtServerInit(vuexContext, context)
        resolve()
      })
    )
  },
}

export default {
  state,
  getters,
  mutations,
  actions,
}

现在,在 store/todos.js 内。

'/store/todos.js'

...

const actions = {
  nuxtServerInit(vuexContext, context) {
    return new Promise((resolve, reject) => {
      const todos = []
      vuexContext.commit('todos/setTodos', todos)
      resolve()
    })
  },
}

...

如果您之前像 vuexContext.commit('todos/setTodos', todos) 这样调用,请记住使用 vuexContext.commit('setTodos', todos)

因为现在你的模块在商店包中,NuxtJS 已经为你生成了所有的包导入。

也请注意您的 this.$store.getters,因为它现在也像 this.$store.getters['todos/todos'] 一样进行了重组。