NuxtServerInit 在 Vuex 模块模式下不起作用 - Nuxt.js
Posted
技术标签:
【中文标题】NuxtServerInit 在 Vuex 模块模式下不起作用 - Nuxt.js【英文标题】:NuxtServerInit not working on Vuex module mode - 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
【问题讨论】:
【参考方案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();
)
【讨论】:
关于异步和等待的新 Promise。 ESLint 实际上并不推荐它。 eslint.org/docs/rules/no-async-promise-executor【参考方案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>
【讨论】:
以上是关于NuxtServerInit 在 Vuex 模块模式下不起作用 - Nuxt.js的主要内容,如果未能解决你的问题,请参考以下文章
nuxtServerInit 与 vuex-module-decorators
nuxt - nuxtServerInit & 页面渲染前的store处理 & context
javascript NUXT - nuxtServerInit