vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
47.7k stars 8.33k forks source link

Refs get cleaned/garbage collected before the onLeave and onBeforeLeave transitions hooks #11296

Open JasonGotGithub opened 4 months ago

JasonGotGithub commented 4 months ago

Vue version

v3.4.31

Link to minimal reproduction

https://stackblitz.com/edit/github-gyqmpz-bdzdrb?file=src%2Fpages%2FAbout.vue

Steps to reproduce

Clicking on the navigation link will trigger navigating. In the console the refs for the pages will be logged

What is expected?

The expected behavior is that the refs should trigger errors and have content within it

What is actually happening?

The refs are empty

System Info

No response

Any additional comments?

No response

linzhe141 commented 4 months ago

playground

JasonGotGithub commented 4 months ago

Without an explanation is quite difficult to understand what your intention is of your message @linzhe141 Besides that, the problem of this issue still occurs in your link

LinusBorg commented 4 months ago

I think they just provided a simplified reproduction that doesn't involve a router etc. Which is helpful.

JasonGotGithub commented 4 months ago

Ah okay, makes sense. I agree

JasonGotGithub commented 4 months ago

@LinusBorg @linzhe141 Out of curiosity, what would be the process to solve this bug?

jh-leong commented 4 months ago

The ref is set to null when the component unmounts. Transition leave hooks are triggered when the element is removed.

In your example, when you click the about button, the process is as follows:

  1. Unmount the Home component (pageRef is set to null)
  2. Remove the Home component
  3. Trigger transition leave and afterLeave hooks

This behavior for updating the ref is expected.

By the way, I'm curious why you need to access the ref in the leave hook. Perhaps there's another way to achieve your goal?

JasonGotGithub commented 4 months ago

Hi @jh-leong, thanks for your comment.

Is this different from Vue 2? In Vue 2 refs are available in the leave hooks, which would then be the "opposite" from how it is now. I assume since the destroy sequence is no longer present in Vue 3, that's where the different is?

The reason for making this issue, is that quite some creative developers are having issues with Vue 3 and its transition logic. For certain creative transitions/effects, data from the previous/leaving page are required (e.g. WebGL, page transitions, doing a specific animation of elements on the previous page). Simple example: collecting mouse/animation data to proceed an effect on a new page.

JasonGotGithub commented 4 months ago

Hi @jh-leong!

Is the reason clear or do you want more clarification?

jh-leong commented 4 months ago

Sorry for the late response.

Is this different from Vue 2? In Vue 2 refs are available in the leave hooks, which would then be the "opposite" from how it is now. I assume since the destroy sequence is no longer present in Vue 3, that's where the different is?

I'm not familiar with Vue 2, so I can't answer this question directly.

The reason for making this issue, is that quite some creative developers are having issues with Vue 3 and its transition logic. For certain creative transitions/effects, data from the previous/leaving page are required (e.g. WebGL, page transitions, doing a specific animation of elements on the previous page). Simple example: collecting mouse/animation data to proceed an effect on a new page.

If you need to access data from the previous page in the leave hook, maybe function refs could be a workaround. Check out this playground.

JasonGotGithub commented 3 months ago

Thanks! I'll take a look this week

yangliguo7 commented 3 months ago

@JasonGotGithub maybe u can watch the diff in pageRef value

https://play.vuejs.org/#eNrFVUtv2zAM/iuCL3aB1EaxnTKnWFcE6IZuK9piJ19Um0ncypIhyWmKLP99pPzMa+0OQy+J+dTHTyS19i7KMlxW4I292KQ6Ly0zYKuSCS7nk8SzJvHOE5kXpdKW2ZcS2Jrday5NbnMlb7QqDduwmVYF8zGP/6lzXjMNsyO2iwdV2cYSRk4iFH7ncKUK6OwkbJvX7JnbdLGbPZGpksayks/hFg+fEIT46v779VRAAdKy30xWQpwH9HsyiLhUmFiSh4sJ6MgTMrcOdrvm8R4JE7ZOJGOSFzBmPiHwR6QoVEYKrPA0l7UqNRg/48KAE7l5kSlTciot6ADEiGUI5aTOh954vhIQCjUPfEQI2ifku6am5nDJRQWvOoQkve5lwdjWi0AFtbDZwn0NfAmv4BbkcxA3COT5/Ytp6L/kMgUhIAsO15G29qYWCt64Pkqka8n2zFHAR6WGX66AybnLNcw0sGIG12pxVE8gzhsKFopScAsoMRZn+dJ94OdDZa2S7HMq8vQJRzTA9Fv9S72LU7vAvziqvd8c60YRgzn9D6Kb+L7p2fL0IZcZrYjtQXD7gpxdwF1lSpCmrqLTpt2JOGuYouEs8dg4Nyh3iFATDdNFe/niqMdUUxXVXMXRgEFvhJsM6Z/l8/DRKInrzt1I4hGUXID+WVIGRD9u7z3xuBDq+ZvTWV3Vw+piFpA+HdA/mhXpEu9GgwG9xFvobJbrOWA9ZJ7e/YAVfndG3BGVQO+/GG8BW6cijLXbl0pmCHvg59B+dfsxl/N7M11ZZKotioD23Z54uDGJ5WOl93A/hB9dHHYpstitanow9lqUpYIbukDqPby7/na7rogXZ42axrHvtMXZ8dtDcfg29e/RwSemfwKaXd7u+maR47E7hgxmuYTpqlQGAkcBRTuiyJtGnNwG84lMtI/SDhFvomGPBErWcHCEgX/g4H9RMGDA2/wB5YbFHg==

edison1105 commented 2 weeks ago

This behavior is different from vue2. see https://codesandbox.io/p/sandbox/vue-2-playground-forked-2jn5f7?workspaceId=28b40334-b6d1-4971-a748-f2552025b31c