javascript Nuxt + Vuex - 如何将 Vuex 模块分解为单独的文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/53446792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Nuxt + Vuex - How do I break down a Vuex module into separate files?
提问by Guy Harper
In the Nuxt documentation (here) it says 'You can optionally break down a module file into separate files: state.js, actions.js, mutations.jsand getters.js.'
在Nuxt文件(在这里),它说:“你可以在模块文件有可能分解为单独的文件:state.js,actions.js,mutations.js和getters.js。”
I can't seem to find any examples of how this is done - lots of breaking down the Vuex store at the root level into state.js, actions.js, mutations.jsand getters.js, and into individual module files, but nothing about breaking the modules themselves down.
我似乎找不到任何关于如何完成此操作的示例 - 将根级别的 Vuex 存储区分解为state.js、actions.js、mutations.js和getters.js以及单个模块文件,但没有将模块本身分解。
So currently I have:
所以目前我有:
├── assets
├── components
└── store
├── moduleOne.js
├── moduleTwo.js
└── etc...
And what I would like to have is:
我想要的是:
├── assets
├── components
└── store
└── moduleOne
└── state.js
└── getters.js
└── mutations.js
└── actions.js
└── moduleTwo
└── etc...
To try this out, in /store/moduleOne/state.jsI have:
为了试试这个,/store/moduleOne/state.js我有:
export const state = () => {
return {
test: 'test'
}
};
and in /store/moduleOne/getters.jsI have:
和/store/moduleOne/getters.js我有:
export const getters = {
getTest (state) {
return state.test;
}
}
In my component I'm accessing this with $store.getters['moduleOne/getters/getTest']
在我的组件中,我正在访问它 $store.getters['moduleOne/getters/getTest']
However using the debugger and Vue devtools, it seems like state isn't accessible in the getters file - it seems to be looking for a state in the local file, so state.testis undefined.
然而,使用调试器和 Vue devtools,似乎状态在 getters 文件中不可访问 - 它似乎在本地文件中寻找状态,因此state.test未定义。
Attempting to import statefrom my state.jsfile into my getters.jsfile doesn't seem to work either.
尝试state从我的state.js文件导入到我的getters.js文件中似乎也不起作用。
Does anyone have an example of how they've managed to break the store down like this in Nuxt?
有没有人举个例子说明他们如何在 Nuxt 中像这样打破商店?
采纳答案by Corentin Marzin
I am using nuxt 2.1.0If you want to have something like this :
我正在使用 nuxt2.1.0如果你想要这样的东西:
In my store/index.js
在我的 store/index.js
Make sure you have namespaced: true
确保你有命名空间:true
import Vuex from 'vuex';
import apiModule from './modules/api-logic';
import appModule from './modules/app-logic';
const createStore = () => {
return new Vuex.Store({
namespaced: true,
modules: {
appLogic: appModule,
api: apiModule
}
});
};
export default createStore
In moduleOne
在模块一中
In my store/api-logic/index.js
在我的 store/api-logic/index.js
import actions from './actions';
import getters from './getters';
import mutations from './mutations';
const defaultState = {
hello: 'salut I am module api'
}
const inBrowser = typeof window !== 'undefined';
// if in browser, use pre-fetched state injected by SSR
const state = (inBrowser && window.__INITIAL_STATE__) ? window.__INITIAL_STATE__.page : defaultState;
export default {
state,
actions,
mutations,
getters
}
In my store/api-logic/getters.js
在我的 store/api-logic/getters.js
export default {
getHelloThere: state => state.hello
}
In module Two
在模块二中
In my store/app-logic/index.js
在我的 store/app-logic/index.js
import actions from './actions';
import getters from './getters';
import mutations from './mutations';
const defaultState = {
appLogicData: 'bonjours I am module Logic'
}
const inBrowser = typeof window !== 'undefined';
// if in browser, use pre-fetched state injected by SSR
const state = (inBrowser && window.__INITIAL_STATE__) ? window.__INITIAL_STATE__.page : defaultState;
export default {
state,
actions,
mutations,
getters
}
In my store/app-logic/getters.js
在我的 store/app-logic/getters.js
export default {
getAppLogicData: state => state.appLogicData
}
Anywhere in the app
应用程序中的任何位置
computed: {
...mapGetters({
logicData: 'getAppLogicData',
coucou: 'getHelloThere'
})
},
mounted () {
console.log('coucou', this.coucou) --> salut I am module api
console.log('logicData', this.logicData) --> bonjours I am module Logic
}
Bonus Point
奖励积分
If you want to communicate between the modules for example a action in app-logic which trigger something in api-logic. So app-logic (module one) to api-logic (module two)
如果您想在模块之间进行通信,例如 app-logic 中的一个操作会触发 api-logic 中的某些内容。所以app-logic(模块一)到api-logic(模块二)
When you specify root: trueit will start to look at the root of the store.
当您指定时root: true,它将开始查看商店的根目录。
In store/app-logic/actions.js
在 store/app-logic/actions.js
callPokemonFromAppLogic: ({ dispatch }, id) => {
dispatch('callThePokemonFromApiLogic', id, {root:true});
},
In store/api-logic/actions.js
在 store/api-logic/actions.js
callThePokemonFromApiLogic: ({ commit }, id) => {
console.log('I make the call here')
axios.get('http://pokeapi.salestock.net/api/v2/pokemon/' + id).then(response => commit('update_pokemon', response.data))
},
In store/api-logic/index.jsadd another entry
在store/api-logic/index.js另一项添加
import actions from './actions';
import getters from './getters';
import mutations from './mutations';
const defaultState = {
appLogicData: 'bonjours I am module Logic',
pokemon: {}
}
const inBrowser = typeof window !== 'undefined';
// if in browser, use pre-fetched state injected by SSR
const state = (inBrowser && window.__INITIAL_STATE__) ? window.__INITIAL_STATE__.page : defaultState;
export default {
state,
actions,
mutations,
getters
}
In store/api-logic/mutations.jsadd the pokemon mutation :p
在store/api-logic/mutations.js添加口袋妖怪突变:P
update_pokemon: (state, pokemon) => {
state.pokemon = pokemon
}
Anywhere in the app :
应用程序中的任何位置:
computed: {
...mapGetters({
bidule: 'bidule',
pokemon: 'getPokemon'
})
},
mounted() {
console.log('bidule', this.bidule)
this.callPokemonFromAppLogic('1') --> the call
console.log('the pokemon', this.pokemon.name) --> 'bulbasaur'
},
methods: {
...mapActions({
callPokemonFromAppLogic: 'callPokemonFromAppLogic'
}),
}
At the end your Vue devTool should look like this :)

And Voilà I hope It was clear. Code example :
瞧,我希望这很清楚。代码示例:
回答by manniL
Your issue
你的问题
Use defaultexports in your files to achieve the desired effect (no named exports except in the index.js)
使用default出口文件,以达到预期的效果(除了没有名为出口index.js)
Example
例子
An example can be found directly in the Nuxt.js test suite (at https://github.com/nuxt/nuxt.js/tree/dev/test/fixtures/basic/store/foo).
一个例子可以直接在 Nuxt.js 测试套件中找到(在https://github.com/nuxt/nuxt.js/tree/dev/test/fixtures/basic/store/foo)。
If you'd run the basicfixture and access the /store page you'll see the following result
如果您运行basic夹具并访问 /store 页面,您将看到以下结果
The "repeated" contents in the module itself just show that the split-up values take priority (otherwise getValwouldn't return 10 but 99 and state.valwouldn't be 4 but 2).
模块本身中的“重复”内容仅表明拆分值具有优先权(否则getVal不会返回 10 而是 99,state.val也不会返回4 而是 2)。
store.vue code:
store.vue 代码:
<template>
<div>
<h1>{{ baz }}</h1>
<br>
<p>{{ $store.state.counter }}</p>
<br>
<h2>{{ getVal }}</h2>
<br>
<h3>{{ getBabVal }}</h3>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters('foo/bar', ['baz']),
...mapGetters('foo/blarg', ['getVal']),
...mapGetters('bab', ['getBabVal'])
}
}
</script>

