使用 Nuxt.js 时动态 Vuex 模块初始化的最佳方法是啥?

Posted

技术标签:

【中文标题】使用 Nuxt.js 时动态 Vuex 模块初始化的最佳方法是啥?【英文标题】:What is the best approach in dynamic Vuex module initialisation when using Nuxt.js?使用 Nuxt.js 时动态 Vuex 模块初始化的最佳方法是什么? 【发布时间】:2020-03-09 18:07:44 【问题描述】:

最近,我一直在构建一个使用大量独立 Vuex 模块的大型应用程序。让我们来看看其中一个(例如support-chat)。支持聊天位于它自己的单独页面上,在初始应用程序加载时使用此模块污染商店将是多余的。我的目标是在加载页面时动态注册此模块。所以我的问题是——我应该在哪里、何时以及如何注册该模块?

我最终在页面组件的beforeCreate钩子中注册了这个模块:

import supportChatModule from '@/vuex/modules/support-chat'

// ...
beforeCreate() 
  this.$store.registerModule('support-chat', supportChatModule,  preserveState: process.client )
,
beforeDestroy() 
  this.$store.unregisterModule('support-chat')

// ...

这种方法有什么缺陷?

如果您能分享您解决该问题的方法,那就太好了。

【问题讨论】:

为什么默认设置不适合您?能详细点吗? 【参考方案1】:

我为这个问题苦苦挣扎了很长时间。我终于想出了一个独特的方法。 我通过将registerunregister 的每个页面的模块移动到beforeEach 方法中的router file(我的项目中的router/index.js)并为每个path 添加所需的模块来做到这一点。

部分模块在页面之间共享,解决了这个问题。 有些模块从服务器接收大量数据,这比留在客户端要好,以避免再次接收到这些数据。我是用冰箱做的。

这个方法可以改进。

路由器/index.js

router.beforeEach((to, from, next) => 

  // unregister modules
  if (from.meta.modules) 
    for (const key in from.meta.modules.primary) 
      if (to.meta.modules && to.meta.modules.primary.hasOwnProperty(key)) 
        continue;
      
      if (store.state.hasOwnProperty(key)) 
        // don't unregister freeze modules
        if (from.meta.modules.hasOwnProperty('freeze') && from.meta.modules.freeze.find(item => item == key)) 
          continue;
        
        store.unregisterModule(key);
      
    
  
  // register modules
  if (to.meta.modules) 
    for (const key in to.meta.modules.primary) 
      const module = to.meta.modules.primary[key]();
      if (!store.state.hasOwnProperty(key)) 
        store.registerModule(key, module.default);
      
    
  
);

而我的路径是这样的:


  path: 'users',
  name: 'users',
  meta: 
    modules: 
      primary: 
        user: () => require('@/store/modules/moduleUser')
      
    ,
  ,
  component: () => import('../views/users.vue')
,


  path: 'foods',
  name: 'foods',
  meta: 
    modules: 
      primary: 
        food: () => require('@/store/modules/moduleFood'),
        user: () => require('@/store/modules/moduleUser')
      ,
      freeze: ['food']
    ,
  ,
  component: () => import('../views/foods.vue')
,

【讨论】:

看起来不错,期待看看【参考方案2】:

第 1 步:

创建一个mixin,我把它命名为register-vuex-module.js

export const registerVuexModule = (name, module) => (
  beforeCreate() 
    const  $store  = this

    if ($store.hasModule(name)) $store.commit(`$name/resetState`)
    else $store.registerModule(name, module().default)
  
)

第 2 步: 使用 mixin 导入模块:

<template>
...
</template>

<script>
// Mixins
import  registerVuexModule  from '@/mixins/register-vuex-module'

export default 
  mixins: [registerVuexModule('module-name', () => require('./vuex/MyVuexModule.js'))],

</script>

第 3 步:

确保您的 Vuex 模块具有 resetState 突变,并且状态也从函数返回。以下是MyVuexModule.js 的示例:

const initialState = () => (
  count: null
)

export default 
 namespaced: true,

 state: initialState(),

 mutations: 
  // ...
  resetState: state => Object.assign(state, initialState())
 

【讨论】:

以上是关于使用 Nuxt.js 时动态 Vuex 模块初始化的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Jest 测试 NUXT.js 和 Vue.js 应用程序。获取“在 mapState() 中找不到 [vuex] 模块命名空间”和“[vuex] 未知操作类型”

如何使用 Nuxt.js 在 vuex 状态中获取本地存储数据

Vuex Mutation 不适用于 Nuxt.js

在 Nuxt JS vuex 中使用 Vue Router 重定向

名称空间模块auth的vuex重复名称空间auth /

Nuxt.js vuex 存储未持久化