vue-hot-reload-api
vue-hot-reload-api copied to clipboard
VueRouter beforeRouteEnter hook data changes are not reloaded
Hi,
thanks for your work on hot reload!
I'm using vue-hot-reload-api implicitly with webpack dev server and vue-loader. When introducing vue-router into the mix and declaring a beforeRequestEnter hook, hot reloading does not work.
Expected behaviour
Hot reloading should reload data set by vue-routers beforeRequestEnter hook as well.
Actual behaviour
The beforeRequestEnter hook is executed, but the data set on the instance is not reloaded.
Steps to reproduce
Clone https://github.com/stoically/vue-router-hot-reload-issue (based on vue init webpack-simple)
npm install
npm run dev
Navigate to http://localhost:8080
You'll see Message from VueRouter: beforeRouteEnter
Now make a change in the src/Router.vue file
Message changes to Message from VueRouter: data
Notes
I'm actually not sure if this is expected behaviour. But if it is I would appreciate any pointers on how to achieve hot reloading in this case manually.
Best regards
I have been running into this issue this week while looking at moving our product to using beforeRouteEnter guards to preload data. Seems this becomes a non-starter from a development experience though if every time we change the file I have to do a full reload and lose my HMR because the fetched data vanishes?
Any updates or guidance would be appreciated.
I'm also having this issue where all my routes fetch data in the beforeRouteEnter hook as prescribed in the router docs , however this hook is not fired by hot-reload and all data are removed from the component, forcing me to do a full manual reload of the page.
Will the router hooks be supported by hot-reload or are we left with cmd+r for the unforeseeable future?
me too
yeah having the same issue, my workaround atm is while developing set the data in the mounted hook.
Be cool to get attention on this issue. Guess i have to forgo HMR for now.
It has been a while and it seems this still is an issue. Any updates on this?
Workaround for Vue2
It will be useful in 95%+ cases when editing a component. In other cases, you will need to reload the page.
// unique for component
let hmrName = 'some-string';
export default {
created() {
if (window[hmrName]) {
Object.assign(this._data, window[hmrName]._data);
}
},
mounted() {
window[hmrName] = this;
},
destroyed() {
delete window[hmrName];
},
}
As a mixin with parameters
// src/mixins/hmr.js
export function vHmrStateMixin(name) {
// NOTE: use only in DEV
if (!process.env.DEV) {
return {};
}
let store = window._devHmr = window._devHmr || Object.create(null);
return {
created() {
if (store[name]) {
Object.assign(this._data, store[name]._data);
}
},
mounted() {
store[name] = this;
},
destroyed() {
delete store[name];
},
};
}
// src/views/Home.vue
export { vHmrStateMixin } from '@/mixins/hmr';
export default {
mixins: [vHmrStateMixin('home')],
beforeRouteEnter(to, from, next) { ... },
}
Explanation
HMR executes hooks:
NEW.beforeCreate
NEW.created
NEW.beforeMount
OLD.beforeDestroy
OLD.destroyed
NEW.mounted
The order of events is important.
We restore the data (_data) as early as possible, in the created hook, when the data has already been initialized. The beforeCreated hook doesn't work for us.
Saving in the mounted hook, and cleaning up in the destroyed hook. These are the only places where we can do it.
When the component is destroyed (for example, when changing the page), the destroyed hook will be called, which will remove the reference to the last instance of the component from window.
There will be NO memory leaks =)
We use window because we need global storage, but <script> inside * .vue files has local scope.