【问题标题】:NuxtServerInit not working on Vuex module mode - Nuxt.jsNuxtServerInit 在 Vuex 模块模式下不起作用 - Nuxt.js
【发布时间】:2019-07-22 08:53:15
【问题描述】:

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
}

【问题讨论】:

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


    【解决方案1】:

    docs中所说

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

    所以你需要把你的 nuxtServerInit 放到 store/index.js 中

    【讨论】:

    • 你能举个例子说明如何做到这一点。
    • @Ninja 在文档和示例中。 github.com/nuxt/nuxt.js/blob/…
    • 是的,但我的 Vuex 处于模块模式。所以有点困惑。
    • @Ninja 我也以模块模式链接的示例
    • @Aldarund 不确定您的示例是否已更改,但似乎没有处于模块模式?
    【解决方案2】:

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

         export const actions = {
    
      nuxtServerInit ({ dispatch }) {
        console.log("troololollo")
      }
    }
    

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

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

    【讨论】:

    • mode: spa 不会进行 nuxtServerInit 调用。我经过惨痛的教训才学到这个。感谢您的评论。
    【解决方案3】:

    你只能从 store/index.js 中调用 nuxtServerInit 是不对的

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

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

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

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

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

    【讨论】:

    • 嘿安德烈,当您只想指出它是代码时,您可以使用“预代码”格式({} 图标)而不是可执行的 sn-p 格式( 图标)。
    【解决方案4】:

    参考文档对这些问题的回答如此之多,但没有人提及如何实际“从 [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();
        })
      }
    }
    

    【讨论】:

    【解决方案5】:

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

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

    因为现在您的模块位于 store 包中,并且 NuxtJS 已经为您生成了所有包导入。

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

    【讨论】:

      【解决方案6】:

      你就不能这样吗……

      index.js

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

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

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

      【讨论】:

        猜你喜欢
        • 2020-05-31
        • 2019-12-11
        • 1970-01-01
        • 2021-05-04
        • 2019-10-19
        • 2019-04-04
        • 1970-01-01
        • 2019-03-07
        • 2020-04-21
        相关资源
        最近更新 更多