Description
Please refer to this section 'Store Code Splitting'.
{
// here follows critical code in given demo
computed: {
fooCount () {
return this.$store.state.foo.count;
},
},
serverPrefetch () {
this.registerFoo()
return this.fooInc()
},
mounted () {
this.registerFoo()
},
destroyed () {
this.$store.unregisterModule('foo')
},
methods: {
registerFoo () {
this.$store.registerModule('foo', fooStoreModule, { preserveState: true })
},
},
}
Given that we have a route componet Fruit with path '/fruits/:id'. At the first time we visit the page '/fruits/1', during server-side rendering, store module 'foo' will be registered and the final global state will be injected into HTML as window.__INITIAL__STATE
, once client app start hydrating, client app's state will be replaced by window.__INITIAL__STATE
, after entering the route /fruits/:id, module 'foo' will be registered as expected and keeps previous state not changed. So far, that's all ok (except this problem #239 i'v found before). But once you leave this route, destroyed hook will be called and module 'foo' will be unregistered. Then we click history back button, we'll back to this route and since module 'foo' has not been registered yet, computed property fooCount
will cause an TypeError because this.$store.state.foo
is undefined.
Oops...That's not the biggest problem! The worst thing is that after mounted hook called and this.registerFoo()
called, the 'foo' module will still be registered with option { preserveState: true }
and as a result this.$store.state.foo
will always be undefined (previous state has no property 'foo' due to unregistration).
That's the problem.
Here follows my solution: no duplicated module registration and no unregistration, then everything will be ok.
{
computed: {
fooCount () {
return this.$store.state.foo.count;
},
},
methods: {
registerFoo(preserve = false) {
if (!this.$store._modules.root._children['foo']) {
this.$store.registerModule('foo', storeModuleFoo, { preserveState: preserve });
}
},
},
serverPrefetch() {
this.registerFoo();
return this.fooInc();
},
mounted() {
this.registerFoo(true);
},
}
I'm not sure is this solution valid, please give your advice if anything went wrong, thanks all.