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

And*_*huk 7 store vue.js server-side-rendering vuex nuxt.js

最近,我一直在构建一个使用大量独立 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')
}
// ...
Run Code Online (Sandbox Code Playgroud)

这种方法有什么缺陷?

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

小智 4

我为这个问题苦苦挣扎了很长时间。我终于想出了一个独特的方法。我通过将每个页面的模块移动registerunregisterrouter filerouter/index.js我的项目中)beforeEach方法中并为每个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);
      }
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

我的路径是这样的:

{
  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')
},
Run Code Online (Sandbox Code Playgroud)