【问题标题】:Nuxt + Vuex - How do I break down a Vuex module into separate files?Nuxt + Vuex - 如何将 Vuex 模块分解为单独的文件?
【发布时间】:2019-04-26 01:44:07
【问题描述】:

在 Nuxt 文档 (here) 中,它说“您可以选择将模块文件分解为单独的文件:state.jsactions.jsmutations.jsgetters.js。”

我似乎找不到任何关于如何做到这一点的示例 - 大量将根级别的 Vuex 存储分解为 state.jsactions.jsmutations.jsgetters.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 上创建一个问题。似乎是错误或缺少文档。
  • @manniL 的上述回答并没有解决问题,因为模块目录的内容只是在商店根目录中的同名文件中重复
  • 抱歉,我现在了解更多细节;)

标签: javascript vue.js vuex nuxt.js


【解决方案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 SSR
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 SSR
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 SSR
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>
      

      【讨论】:

        猜你喜欢
        • 2021-01-31
        • 2021-11-28
        • 2020-08-21
        • 2021-01-06
        • 2017-03-26
        • 2019-05-16
        • 2021-01-23
        • 2021-07-15
        • 1970-01-01
        相关资源
        最近更新 更多