Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJS hook mounted() is not called when page is re-open by vue-router

Please, look the flux below, it's shows my problem. I'm using vue-router with this.$router.push to browsing on pages. I'm starting on PageA.

  • PageA -> PageB ( mounted() of PageB is called)

  • PageB -> PageA (returning to PageA)

  • PageA -> PageB (mounted() of PageB is not called)

It sounds that page (.vue component) is not closed and mainted on cache or other thing. I must use the mounted() method every time that page is open and maybe close the page and clean from cache. How I can solve it?

like image 269
Augusto Avatar asked Aug 28 '19 20:08

Augusto


People also ask

What is a mounted hook in Vue?

May 11, 2020 The mounted () hook is the most commonly used lifecycle hook in Vue. Vue calls the mounted () hook when your component is added to the DOM. It is most often used to send an HTTP request to fetch data that the component will then render.

When does the created () hook run in a Vue component?

Vue runs the created () hook when the component object is created, before the component is mounted to the DOM. The Vue docs recommend using the mounted () hook over the created () hook for data fetching. This point is often debated.

What is the difference between created () and mounted () in Vue?

Vue calls a global error handler whenever a lifecycle hook throws an error, whether the error was sync or async. Vue has another lifecycle hook that is similar to mounted () : the created () hook. Vue runs the created () hook when the component object is created, before the component is mounted to the DOM.

What happens when a Vue Hook throws an error?

Vue calls a global error handler whenever a lifecycle hook throws an error, whether the error was sync or async. Vue has another lifecycle hook that is similar to mounted () : the created () hook.


2 Answers

Vue 3

For those that ended up here like me looking at why I'm not getting unmounted called on a component inside a page, when route changes, here's some guidance:

Let's say you have Page A that uses Component A in it, and Page B that does not use Component A.

When you open Page A for the first time, Component A will have, as expected, mounted method called.

However, when you navigate to Page B, Vue3 won't un-mount or destroy Component A, rather it will deactivate it, and deactivated method will be called instead of unmounted.

Once you navigate back to Page A, Component A will be reactivated and method activated will be called instead of mounted.

like image 115
Siniša Avatar answered Oct 22 '22 08:10

Siniša


vue will re-use components were possible, this is expected.
Normally you would watch for route changes and update your component state accordingly.

To react to route changes you can use beforeRouteUpdate():

const Example = Vue.extend({
  template: `
  	<div>
  		<p>This changes: '{{param}}'</p>
    </div>`,
  data(){
    return {
      param: this.$route.params.param
    };
  },
  beforeRouteUpdate(to, from, next) {
    this.param = to.params.param;
    next();
  }
});

const router = new VueRouter({
  routes: [
    {
      path: '/:param', component: Example,
    }
  ]
})
const app = new Vue({ router }).$mount('#app')
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
  <router-link to="/foo">foo</router-link><br>
  <router-link to="/bar">bar</router-link><br>
  <router-view></router-view>
</div>

Alternatively you can also watch the route and update the state accordingly:

Vue.extend({
  watch: {
    '$route'() {
      // TODO: react to navigation event.
      // params cotains the current route parameters
      console.log(this.$route.params);
    }
  },
  // ....
});

The vue-router documentation has a few great examples for this: Data Fetching - Vue Router

If you still want to use mounted(), you can do so by giving your router-view a key that will change when the route changes, e.g.:

<router-view :key="$route.fullPath"></router-view>

This will force the component to be re-created every time, so it does have a performance penalty - i would recommend using the route hooks described above, if possible.

like image 21
Turtlefight Avatar answered Oct 22 '22 10:10

Turtlefight