Nuxt.js: new fetch with keep-alive being fetched while keeped-alive

Created on 30 Mar 2020  路  7Comments  路  Source: nuxt/nuxt.js

Version

v2.12.1

Reproduction link

https://example.com

Steps to reproduce

When you use the new fetch with <nuxt keep-alive> and a query watcher this watcher is called even though the component is not active (but keeped-alive)

What is expected ?

It should not fetch

What is actually happening?

It fetches

bug-report

Most helpful comment

https://codesandbox.io/s/youthful-archimedes-l3by4

Fetch should only occur on index route, to see the problem please navigate forth and back on the About page.

@Atinux could you please remove the need repro label

All 7 comments

Please create a reproduction by forking https://template.nuxtjs.org

https://codesandbox.io/s/youthful-archimedes-l3by4

Fetch should only occur on index route, to see the problem please navigate forth and back on the About page.

@Atinux could you please remove the need repro label

Bump, running into this as well.

@Atinux, The same problem when use:

watch: { 
  '$route.query': '$fetch' 
}

Reproduction link: https://codesandbox.io/s/elated-smoke-ht94h

It seems that $fetch runs for any route change, not only on current page query change, and ignoring keep-alive. Check console and you will see "fetched" message while navigating between pages.

Hi there, sorry for the delay.

Actually, it's directly due to Vue & Vue-Router watch system, it seems that watch on $route.query is triggered for any route changes (even if query is still the same...).

When you call $fetch, it won't care if you are using a keep-alive. It's only when doing navigation that it won't call fetch because the component is cached.

One solution would be to check if the query has changed, we can do this by using JSON.stringify:

watch: {
    '$route.query': function(newQuery, oldQuery) {
      if (JSON.stringify(newQuery) !== JSON.stringify(oldQuery)) {
        console.log('Query changed')
        this.$fetch()
      }
    }
  }

Then, it seems that the function is called when leaving the page (because of keep-alive), you can check this._inactive to know if the component is inactive to avoid triggering fetch again:

watch: {
    '$route.query': function (newQuery, oldQuery) {
      if (this._inactive === false && JSON.stringify(newQuery) !== JSON.stringify(oldQuery)) {
        console.log('Query changed')
        this.$fetch()
      }
    }
  }

One solution would be to directly watch the property you want to watch in $route.query:

watch: {
    '$route.query.test': function (newQuery, oldQuery) {
      if (this._inactive === false) {
        console.log("Query changed")
        this.$fetch()
      }
    }
  },

Demo: https://codesandbox.io/s/empty-dream-xqjgv?file=/pages/test/index.vue

To be honest, this is not a solution, this is a workaround that will brick in the next release...

Also, if this is the 'solution' it should be documented.

You can always open an issue on vue-router repo since it's actually not directly related to Nuxt.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

VincentLoy picture VincentLoy  路  3Comments

lazycrazy picture lazycrazy  路  3Comments

mikekidder picture mikekidder  路  3Comments

pehbehbeh picture pehbehbeh  路  3Comments

bimohxh picture bimohxh  路  3Comments