Lately, I have been building a large scale application that uses a lot of separate Vuex modules. Let's take a look at one of them (eg support-chat
). Support chat is located on it's own separate page, and it would be redundant to pollute the store with this module on initial application load. My goal is to register this module dynamically when it's page is loaded. So my question is – where, when and how should I register that module?
I end up registering this module in the beforeCreate
hook of the page component:
import supportChatModule from '@/vuex/modules/support-chat'
// ...
beforeCreate() {
this.$store.registerModule('support-chat', supportChatModule, { preserveState: process.client })
},
beforeDestroy() {
this.$store.unregisterModule('support-chat')
}
// ...
What pitfalls does that approach have?
It would be great if you can share your approach in solving that issue.
I struggled with this problem for a long time. I finally came up with a unique way. I did this by moving register
and unregister
the modules for each page into the router file
( router/index.js
in my project) in beforeEach
method and adding the required modules for each path
.
This method can be improved.
router/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); } } } });
And my paths are like this:
{ 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') },
I have tried different solutions but overtime I faced issues.
I will update my answer if I find any issues with it
import myModule from './my-module.js'
export default {
// ...
beforeCreate() {
this.isRouterLeaving = false
if (this.$store.hasModule('my-module')) {
this.$store.unregisterModule('my-module')
}
this.$store.registerModule('my-module', myModule)
},
beforeRouteLeave(to, from, next) {
this.isRouterLeaving = true
next()
},
beforeDestroy() {
if (this.isRouterLeaving) this.$store.unregisterModule('subscription-show')
},
// ...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.