Nuxt.js: Data called twice when navigating from child to child route

Created on 4 Jul 2018  ·  25Comments  ·  Source: nuxt/nuxt.js

Version

v1.4.0

Reproduction link

https://github.com/vedmaque/nuxt-double-data

Steps to reproduce

  • Create pages/parent.vue
<template>
  <nuxt-child />
</template>
  • Create pages/parent/child1.vue
<template>
  <nuxt-link to="/parent/child2">Go to Child 2 Page</nuxt-link>
</template>
  • Create pages/parent/child2.vue
<template>
  <nuxt-link to="/parent/child1">Go to Child 1 Page</nuxt-link>
</template>

<script>
export default {
  data () {
    console.log('child2.vue data')
    return {}
  },
  created () {
    console.log('child2.vue created')
  },
  mounted () {
    console.log('child2.vue mounted')
  }
}
</script>
  • Navigate from Child 1 to Child 2.
  • Log in console:
child2.vue data
child2.vue created
child2.vue mounted
child2.vue data

What is expected ?

Expect that data() called only once and not after mounted().

What is actually happening?

Data() called second time after mounted().

Additional comments?

  • It works fine when use simple Vue app with Vue-router.
  • Changing parent.vue template to
<template>
  <div>
    <nuxt-child />
  </div>
</template>

fixes the issue.

  • I think that issue at fixPrepatch function at client.js:391 (not sure what happens, but)
This bug report is available on Nuxt community (#c7324)
bug-report pending

Most helpful comment

Still happens in 2.8.1, exactly this way.

All 25 comments

I can reproduce this as long as data isn't altered

If you change child2.vue to the following, the 2nd call disappears:

<template>
  <div>
    <h3>Parent / Child 2 Page</h3>
    <nuxt-link to="/parent/child1">Now go back to Child 1 Page</nuxt-link>
    <p>Or you could just press back button in browser</p>
  </div>
</template>

<script>
export default {
  data() {
    console.log('parent/child2.vue data')
    return { a: 1 }
  },
  created() {
    console.log('parent/child2.vue created')
  },
  mounted() {
    this.a = 2
    console.log('parent/child2.vue mounted')
    setTimeout(() => console.log({a: this.a}), 2000, )
  }
}
</script>

@manniL the 2nd call only happens on in page routing not refreshing the page

I've test some scenario, and the potential causes are

  1. like vedmaque post above, using nuxt-child as root element in a vue template (can be fix by wrapping it using a div)
  2. accidentally using router-view tag rather than the nuxt-child, the child-route view data function will be call twice.

And this will alter the data on the child route page vue instance like in this (repo)

export default {
  name: 'Page2',
  data() {
    console.log('page2_data_called')
    return {
      token: 'page2_token',
    }
  },
  mounted() {
    this.token = 'page2_token_modified'
    console.log(this.token)
    setTimeout(() => {
      console.log(this.token)
    })
  },
}

When click the link routing from page1 to page2 or page2 to page1, you get console logging like this

page2_data_called
page2_token_modified
page2_data_called
page2_token

The token is changed by somethign after the mounted function, and it looks like the data function called twice and modify the vue instance twice, right after the vue component instance is initialized.

This might cause some unexpected behavior.

same happens on 2.2.0

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

bump

Thanks for your contribution to Nuxt.js!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If you would like this issue to remain open:

  1. Verify that you can still reproduce the issue in the latest version of nuxt-edge
  2. Comment the steps to reproduce it

Issues that are labeled as 🕐Pending will not be automatically marked as stale.

This also happens when navigating from parent to child route.
I found adding transition: { css: false } to the child component fixes the problem.
but I don't know why.

I also ran into this issue today. As @noe132 pointed out, wrapping <nuxt-child> using a div (and not having it as a root component) avoids the issue.

Same here. I'm also facing this issue. When navigating from the parent to a child route after hard browser refresh, data() in the child is called twice. It caueses serious problems in my app. Wrapping nuxt-child in div doesn't work.

Ive solved this issue with not very elegant way, but it works already. In created() hook, I call function which changes data(), but now with delay - debounce(fn, 0)

Same here using version ^2.3.4 @edus44

👍 I have the same issue on spa mode. This seems to work for now on the child route.

mounted() {
    setTimeout(() => {
       // this.someData = 'myData'
    }, 0)
}

Version

v1.4.0

Reproduction link

https://github.com/vedmaque/nuxt-double-data

Steps to reproduce

  • Create pages/parent.vue
<template>
  <nuxt-child />
</template>
  • Create pages/parent/child1.vue
<template>
  <nuxt-link to="/parent/child2">Go to Child 2 Page</nuxt-link>
</template>
  • Create pages/parent/child2.vue
<template>
  <nuxt-link to="/parent/child1">Go to Child 1 Page</nuxt-link>
</template>

<script>
export default {
  data () {
    console.log('child2.vue data')
    return {}
  },
  created () {
    console.log('child2.vue created')
  },
  mounted () {
    console.log('child2.vue mounted')
  }
}
</script>
  • Navigate from Child 1 to Child 2.
  • Log in console:
child2.vue data
child2.vue created
child2.vue mounted
child2.vue data

What is expected ?

Expect that data() called only once and not after mounted().

What is actually happening?

Data() called second time after mounted().

Additional comments?

  • It works fine when use simple Vue app with Vue-router.
  • Changing parent.vue template to
<template>
  <div>
    <nuxt-child />
  </div>
</template>

fixes the issue.

  • I think that issue at fixPrepatch function at client.js:391 (not sure what happens, but)

_This bug report is available on Nuxt community (#c7324)_

Wrapping the in a div works for me as well.
But may I ask what was the source for this info. It fixes the issue but I wish its not any kind of hack we are using.

Same here using version ^2.6.2

@Atinux @clarkdo Any thoughts on this? Pretty nasty bug here.

Ran into same issue today.

But I found that if using out-in mode for transition, it will not happen(which is default for nuxt.config.js).

If change the config to in-out mode for transition like below, this bug will happen no matter how <nuxt-child/> is wrapped.

  transition: {
    name: 'page',
    mode: 'in-out'
  }

This behavior will mount $vm twice which is causing this bug. From debugger, i noticed that the this context which is actually mounted is different from the context in data() function.

Temporary workaround for me is to use out-in mode in nuxt.config.js. It will remove the old element first and avoid this bug.

This does not seem to happen anymore in version ^2.8 :smile:

@Atinux, @pi0 can closed?

Indeed :)

Still happens in 2.8.1, exactly this way.

Still happens in 2.8.1, exactly this way.

same problem,any progress?
navigating from parent to child route leads to parent data reset, and navigate to parent path see no sign of life-cycle hooks executed, except for asyncData

It works well in ^2.9.2.

@xpdlf1004 I am still having this exact issue in 2.10.0

Still having same issue v2.11.0.

https://codesandbox.io/s/flamboyant-smoke-1896o

Same issue for me. Any updates?

This issue does not reproduce using [email protected].

I close the issue, feel free to comment or reopen if issue exists in special cases.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vadimsg picture vadimsg  ·  3Comments

danieloprado picture danieloprado  ·  3Comments

msudgh picture msudgh  ·  3Comments

nassimbenkirane picture nassimbenkirane  ·  3Comments

shyamchandranmec picture shyamchandranmec  ·  3Comments