简体   繁体   中英

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?

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, eg:

<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.

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 ofunmounted .

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

For those who are using the Composition API for Vue 3 :

This use case is for fetching data from an API upon component mount and other dependencies. Instead of watch , you need to use watchEffect to automatically track the dependencies and perform side effects on mount.

watchEffect(fetchData);

watch(dependencies, callback) will trigger on first visit to the route. But if you go to another page, then come back to it, it won't trigger again because it does not count the initial state as an update. Also, the dependencies technically did not change from the time it was mounted.

Additional Notes:

  • If you are coming from React, watch is not exactly equivalent to useEffect . watchEffect is more similar to it.

  • For comparison, this code should have the same results as the watchEffect one. But watchEffect is more concise.

onMounted(fetchData);
watch([dependency 1, dependency 2, ...], fetchData);

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM