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>
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>