Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VueRouter beforeRouteEnter hook data changes are not reloaded #64

Open
stoically opened this issue Dec 16, 2017 · 7 comments
Open

VueRouter beforeRouteEnter hook data changes are not reloaded #64

stoically opened this issue Dec 16, 2017 · 7 comments

Comments

@stoically
Copy link

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

@wadetandy
Copy link

wadetandy commented Aug 17, 2018

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.

@jorngeorg
Copy link

jorngeorg commented Oct 22, 2018

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?

@zenghj
Copy link

zenghj commented May 31, 2019

me too

@SeoFood
Copy link

SeoFood commented Sep 4, 2019

yeah having the same issue, my workaround atm is while developing set the data in the mounted hook.

@boycce
Copy link

boycce commented Sep 30, 2019

Be cool to get attention on this issue. Guess i have to forgo HMR for now.

@jacob418
Copy link

It has been a while and it seems this still is an issue. Any updates on this?

@igisev
Copy link

igisev commented Sep 15, 2021

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants