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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 10:11:49  来源:igfitidea点击:

Nuxt + Vuex - How do I break down a Vuex module into separate files?

javascriptvue.jsvuexnuxt.jsnuxt

提问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.jsactions.jsmutations.jsgetters.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.jsactions.jsmutations.jsgetters.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如果你想要这样的东西:

Store module Vuex with Nuxt

使用 Nuxt 存储模块 Vuex

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 :) Vue devTool screenshot store

最后你的 Vue devTool 应该是这样的 :) Vue devTool截图存储

And Voilà I hope It was clear. Code example :

瞧,我希望这很清楚。代码示例:

https://github.com/CMarzin/nuxt-vuex-modules

https://github.com/CMarzin/nuxt-vuex-modules

回答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 页面,您将看到以下结果

enter image description here

在此处输入图片说明

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>