Nuxt + Vuex - 如何将 Vuex 模块分解为单独的文件?
Posted
技术标签:
【中文标题】Nuxt + Vuex - 如何将 Vuex 模块分解为单独的文件?【英文标题】:Nuxt + Vuex - How do I break down a Vuex module into separate files? 【发布时间】:2019-04-26 01:44:07 【问题描述】:在 Nuxt 文档 (here) 中,它说“您可以选择将模块文件分解为单独的文件:state.js
、actions.js
、mutations.js
和 getters.js
。”
我似乎找不到任何关于如何做到这一点的示例 - 大量将根级别的 Vuex 存储分解为 state.js
、actions.js
、mutations.js
和 getters.js
,并分解为单个模块文件,但没有关于分解模块本身的内容。
所以目前我有:
├── assets
├── components
└── store
├── moduleOne.js
├── moduleTwo.js
└── etc...
而我想要的是:
├── assets
├── components
└── store
└── moduleOne
└── state.js
└── getters.js
└── mutations.js
└── actions.js
└── moduleTwo
└── etc...
要试试这个,/store/moduleOne/state.js
我有:
export const state = () =>
return
test: 'test'
;
在/store/moduleOne/getters.js
我有:
export const getters =
getTest (state)
return state.test;
在我的组件中,我使用 $store.getters['moduleOne/getters/getTest']
访问它
但是使用调试器和 Vue 开发工具时,似乎无法在 getters 文件中访问状态 - 它似乎正在本地文件中寻找状态,因此 state.test
未定义。
尝试将state
从我的state.js
文件导入我的getters.js
文件似乎也不起作用。
有没有人举个例子说明他们是如何在 Nuxt 像这样打破商店的?
【问题讨论】:
好问题。刚试了一下,它确实破坏了我的应用程序。也许在cmty.app/nuxt 上创建一个问题。似乎是错误或缺少文档。 示例在github.com/nuxt/nuxt.js/tree/dev/test/fixtures/basic/store/foo/… ;) @manniL 的上述回答并没有解决问题,因为模块目录的内容只是在商店根目录中的同名文件中重复 抱歉,我现在了解更多细节;) 【参考方案1】:我正在使用 nuxt 2.1.0
如果你想拥有这样的东西:
在我的store/index.js
确保您有 namespaced: 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
在moduleOne中
在我的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 s-s-r
const state = (inBrowser && window.__INITIAL_STATE__) ? window.__INITIAL_STATE__.page : defaultState;
export default
state,
actions,
mutations,
getters
在我的store/api-logic/getters.js
export default
getHelloThere: state => state.hello
在模块二中
在我的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 s-s-r
const state = (inBrowser && window.__INITIAL_STATE__) ? window.__INITIAL_STATE__.page : defaultState;
export default
state,
actions,
mutations,
getters
在我的store/app-logic/getters.js
export default
getAppLogicData: state => state.appLogicData
应用中的任何位置
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
奖励积分
如果您想在模块之间进行通信,例如 app-logic 中的某个操作会触发 api-logic 中的某些内容。 所以 app-logic(模块一)到 api-logic(模块二)
当您指定root: true
时,它将开始查看存储的根目录。
在store/app-logic/actions.js
callPokemonFromAppLogic: ( dispatch , id) =>
dispatch('callThePokemonFromApiLogic', id, root:true);
,
在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))
,
在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 s-s-r
const state = (inBrowser && window.__INITIAL_STATE__) ? window.__INITIAL_STATE__.page : defaultState;
export default
state,
actions,
mutations,
getters
在store/api-logic/mutations.js
中添加口袋妖怪突变:p
update_pokemon: (state, pokemon) =>
state.pokemon = pokemon
应用中的任何位置:
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'
),
最后你的 Vue devTool 应该是这样的 :)
瞧,我希望它很清楚。 代码示例:
https://github.com/CMarzin/nuxt-vuex-modules
【讨论】:
【参考方案2】:在 nuxt 版本 2.14^ 中,您不必在商店根 index.js 文件中创建它。
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
但是,您可以将根 index.js 文件保留为默认文件或执行您需要的操作。无需导入。
store/index.js
export const state = () => (
counter: 0
)
export const mutations =
increment(state)
state.counter++
export const actions =
async nuxtServerInit( state, commit , req )
const cookies = this.$cookies.getAll()
...
它看起来像这样,非常简单。
文件夹结构
?store
┣ ?auth
┣ ?utils
┣ ?posts
┃ ┗ ?actions.js
┃ ┗ ?mutations.js
┃ ┗ ?getters.js
┃ ┗ ?index.js
┣ index.js
例子
store/posts/index.js
你可以只放状态函数。您无需导入操作、getter 和突变。
export const state = () => (
comments: []
)
store/posts/actions.js
const actions =
async getPosts( commit, state , obj)
return new Promise((resolve, reject) =>
...
export default actions
store/posts/mutations.js
const mutations =
CLEAR_POST_IMAGE_CONTENT: (state) =>
state.post_image_content = []
export default mutations
store/posts/getters.js
const getters =
datatest: (state) => state.datatest,
headlineFeatures: (state) => state.headlineFeatures,
export default getters
效果与@CMarzin 答案相同,但更干净
【讨论】:
【参考方案3】:您的问题
在您的文件中使用default
导出以达到预期的效果(除了index.js
之外,没有命名导出)
示例
可以直接在 Nuxt.js 测试套件中找到一个示例(https://github.com/nuxt/nuxt.js/tree/dev/test/fixtures/basic/store/foo)。
如果您运行 basic
夹具并访问 /store 页面,您将看到以下结果
模块本身中的“重复”内容只是表明拆分值优先(否则getVal
不会返回 10 而是 99,state.val
不会返回 4 而是 2)。
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>
【讨论】:
以上是关于Nuxt + Vuex - 如何将 Vuex 模块分解为单独的文件?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Nuxt.js 时动态 Vuex 模块初始化的最佳方法是啥?
使用 Jest 测试 NUXT.js 和 Vue.js 应用程序。获取“在 mapState() 中找不到 [vuex] 模块命名空间”和“[vuex] 未知操作类型”
NuxtServerInit 在 Vuex 模块模式下不起作用 - Nuxt.js