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

NuxtServerInit not working on Vuex module mode - Nuxt.js

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
}

docs

中所述

If you are using the Modules mode of the Vuex store, only the primary module (in store/index.js) will receive this action. You'll need to chain your module actions from there.

所以你需要将你的 nuxtServerInit 放入 store/index.js

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

     export const actions = {

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

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

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

您只能从 store/index.js

中调用 nuxtServerInit 是不正确的

我认为最让我困惑的是模块化方法和只有一个存储文件之间的区别。在后一种方法中,我会做类似的事情:

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

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

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

这对我有用,希望对你有所帮助

这些问题的许多答案都参考了文档,但 none 提到了如何实际“从 [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();
    })
  }
}

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

是的,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

是的,您只需要将它从您的模块包中取出并移动到您的商店包中。

好吧,让我们从 store/index.js 触发 todos.nuxtServerInit

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

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

const actions = {
  async nuxtServerInit(vuexContext, context) {
    await Promise.all([
        todos.actions.nuxtServerInit(vuexContext, context)
    ])
  },
}

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

现在,在 store/todos.js.

里面
'/store/todos.js'

...

const actions = {
  async nuxtServerInit(vuexContext, context) {
    return await vuexContext.commit('todos/setTodos', todos)
  },
}

...

如果您之前像 vuexContext.commit('setTodos', todos) 一样打电话,请记住使用 vuexContext.commit('todos/setTodos', todos)

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

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

能不能不要这样...

index.js

export default {
    state: () => ({
        context: undefined
    }),

    actions: {
        nuxtServerInit ({ state }, ctx) {
            state.context = () => ctx;
        }
    }
};

然后像这样从其他商店调用它...

rootState.context().<some object hanging off of the context>